我理解为什么这会产生编译器错误:
let initialProducer = SignalProducer<Int, NoError>(value:42)
let sideEffectProducer = initialProducer.on(next: { (answer: Int) in
return _
})
错误为
无法将类型为"(Int)->_"的值转换为所需的参数类型'(Int->())?'
因此,当我们返回_
时,next
参数使用返回Void
的Int
参数进行闭包
但为什么这个编译得很好:
let initialProducer = SignalProducer<Int, NoError>(value:42)
let sideEffectProducer = initialProducer.on(next: { (answer: Int) in
return ""
})
我们返回的是String
,而不是Void
,那么编译器为什么不抱怨呢?
_
不是什么。它是模式,或者是可以匹配任何内容的模式的一部分。它也可以用于赋值语句中,以表明您不关心结果。
_ = foo() // Ignore result returned from foo
在你的闭包中,如果你想返回什么都不返回,那么要么:
return
或者如果您在闭包的末尾,则完全省略return。
如果您返回_
,Swift将无法找出您的闭包的签名。您可以通过以下操作来证明这一点:
let bar = { return _ } // Unable to infer closure return type in current context
如果删除_
,它编译得很好,因为bar
变成了() -> ()
。
Swift本可以给你一个更好的错误消息,就像你试图从一个函数返回_
一样:
func foo() {
return _ // '_' can only appear in a pattern or on the left side of an assignment
}
那么,为什么return ""
有效呢?这里有一条线索。
单线闭包有一些明显的奇怪之处。考虑以下与您相似的示例:
func doit(handler: (Int) -> ()) {
handler(17)
print("doit is done")
}
doit() { (answer: Int) in
//print(answer + 1)
return ""
}
运行此操作会产生输出:
doit完成
所以,就像您的示例doit
期望(Int) -> ()
闭包,但我们传递的是(Int) -> String
闭包。它有效。。。
但是,如果取消对print(answer + 1)
行的注释,则return ""
会导致错误:
void函数中出现意外的非void返回