该错误具有误导性:核心是您在函数签名中缺少返回类型... -> Bool,因此尝试将布尔值分配给空元组类型()(使用没有明确的返回类型,该函数期望返回为空元组类型())。
对于将布尔值分配给非布尔类型的任何尝试,您都可以重现此误导性错误,其中布尔值是在与无效分配相同的表达式中执行逻辑 AND/OR 表达式的结果:
var a : () = (true && false) /* same error */
var b : Int = (true && false) /* same error */
var c : () = (true || false) /* same error (for binary op. '||') */
而如果您将 AND/OR 操作包装在一个闭包中,或者只是将它们分配给一个中间布尔变量,您就会丢失混淆的错误消息并显示实际错误。
var d : () = { _ -> Bool in return (true && false) }()
/* Cannot convert call result type 'Bool' to expected type '()' */
var e = true && false
var f : () = e
/* Cannot convert value of type 'Bool' to expected type '()' */
现在为什么你会得到这个误导性错误。两个逻辑运算符 && 和 || 都是通过对其右侧表达式 (rhs) 的条件评估来实现的,因此 rhs 只有在左侧 (lhs) 的情况下才能被延迟评估对于 &&/|| 运算符,分别计算为 true/false。
/* e.g. the AND '&&' logical binary infix operator */
func &&(lhs: BooleanType, @autoclosure rhs: () -> BooleanType) -> Bool {
return lhs.boolValue ? rhs().boolValue : false
}
由于lhs 本身对于后面的赋值无效,可能是惰性闭包rhs 抛出了一个由Bool 类型到() 的“外部”无效赋值引起的错误,但是抛出的错误( “无法应用二进制操作 '&&'...”) 不是 && 调用失败的实际根源。
为了验证,我们可以实现自己的非惰性 AND 运算符,例如 &&&,并且正如预期的那样,我们不会收到相同的混淆错误:
infix operator &&& {
associativity right
precedence 120
}
func &&&(lhs: BooleanType, rhs: BooleanType) -> Bool {
return lhs.boolValue ? rhs.boolValue : false
}
var g : () = false &&& true
/* Cannot convert value of type 'Bool' to expected type '()' */