了解Swift编译器的基本错误



我理解为什么这会产生编译器错误:

let initialProducer = SignalProducer<Int, NoError>(value:42)
let sideEffectProducer = initialProducer.on(next: { (answer: Int) in
  return _
})

错误为

无法将类型为"(Int)->_"的值转换为所需的参数类型'(Int->())?'

因此,当我们返回_ 时,next参数使用返回VoidInt参数进行闭包

但为什么这个编译得很好:

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返回

相关内容

  • 没有找到相关文章

最新更新