我的印象是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
不同的类型吗?
答案 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?) { ... }