我想理解为什么扩展方法有效,而nil-coalescing运算符版本告诉我有一些歧义试图编译它。
typealias SendBlock = ([NSArray]) -> Void
var callbacks = [SendBlock]()
func functionWithArgs(callback: SendBlock?) {
callbacks.append(callback ?? { _ in })
}
func functionWithArgsExpanded(callback: SendBlock?) {
if let cb = callback {
callbacks.append(cb)
} else {
callbacks.append({ _ in })
}
}
答案 0 :(得分:3)
这是因为@autoclosure
的rhs参数上使用了??
。关于这一点意味着它不喜欢实际接收闭包作为被合并的东西的类型。
只是为了演示问题的位置(不要将其作为解决方法),如果在没有它的情况下重新定义??
版本,那就没关系了:
typealias SendBlock = () -> Void
var callbacks = [SendBlock]()
infix operator !! { }
func !!<T>(optional: T?, defaultValue: T)->T {
return optional != nil ? optional! : defaultValue
}
func functionWithArgs(callback: SendBlock?) {
callbacks.append( callback !! { _ in })
}
functionWithArgs { _ in println("blah") }
// just to prove it works… prints “blah”
for x in callbacks { x() }
但是如果修改运算符以使用@autoclosure
:
func !!<T>(optional: T?, @autoclosure defaultValue: ()->T)->T {
return optional != nil ? optional! : defaultValue()
}
你得到错误:
错误:没有更多上下文的表达式类型不明确
callbacks.append( callback !! { _ in }) ^
我说这是一个错误,你应该file a report。在平均时间内,您的解决方法可能是您最好的。
答案 1 :(得分:1)
我认为这只是编译器中的一个错误。如果你在每个有SendBlock的地方替换String,它就可以正常工作。
显然,编译器在使用nil-coalescing运算符时使用Optional包装函数类型。如果你这样写,你会得到更明显的错误:
func functionWithArgs(callback: SendBlock?) {
let sb : SendBlock = { _ in }
callbacks.append(callback ?? sb)
}
错误内容为:“二进制运算符??
无法应用于SendBlock?
和SendBlock
类型的操作数。”对于哪一个人想回复:当然它可以!那些完全 可以应用的各种操作数:一个可选及其未包装的形式。