重载方法,其中只有差异是可选的与非可选的类型

时间:2017-10-07 12:49:45

标签: swift

我的印象是swift可以有重载的方法,这些方法只在方法返回的对象类型上有所不同。我认为我可以有两个具有相同签名的功能但它们的返回类型不同。

import Foundation

// ambiguous use of 'IsTextEmpty(text:)'
func IsTextEmpty(text : String?) -> Bool? {
  return text?.isEmpty
}

func IsTextEmpty(text : String?) -> Bool {
   guard let text = text else {
     return true
   }

   return text.isEmpty
}

let text: String? = nil

if let empty = IsTextEmpty(text:"text") {
   print("Not Empty")
}

if IsTextEmpty(text: text) {
   print("Empty")
}

这里,两个函数都有相同的输入参数,但是一个func返回一个可选的Bool?,另一个返回一个Bool。在这种情况下,我收到一个错误:

ambiguous use of 'IsTextEmpty(text:)'

如果我更改其中一个输入参数的名称,则不再出现模糊错误:

// Works
func IsTextEmpty(foo : String?) -> Bool? {
  return foo?.isEmpty
}

func IsTextEmpty(text : String?) -> Bool {
   guard let text = text else {
     return true
   }

   return text.isEmpty
}

let text: String? = nil

if let empty = IsTextEmpty(foo:"text") {
   print("Not Empty")
}

if IsTextEmpty(text: text) {
   print("Empty")
}

编译器不应该检测到它们是两种不同的方法,即使它们的返回类型不同,因为可选的Bool?是与非可选Bool不同的类型吗?

1 个答案:

答案 0 :(得分:1)

编译器需要一些上下文来决定调用哪种方法,例如

let e1 = IsTextEmpty(text: text) as Bool
let e2: Bool = IsTextEmpty(text: text)

调用非可选变体,或

let e3 = IsTextEmpty(text: text) as Bool?
let e4: Bool? = IsTextEmpty(text: text)

调用可选变体。现在

if IsTextEmpty(text: text) {
    print("Empty")
}

编译没有问题:if语句需要一个布尔值 表达式,所以这里没有歧义。

但显然编译器不够聪明,无法弄明白 在可选绑定的上下文中,右侧的表达式必须是 some 可选 并自动推断未展开的类型。

您需要明确注释empty的类型:

if let empty: Bool = IsTextEmpty(text: text) { ... }

或使返回类型显式:

if let empty = (IsTextEmpty(text: text) as Bool?) { ... }