【问题标题】:Understanding a basic Swift compiler error理解一个基本的 Swift 编译器错误
【发布时间】:2016-05-15 01:30:34
【问题描述】:

我明白为什么这会产生编译器错误:

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

错误是

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

所以next 参数采用带有Int 参数的闭包,该参数返回Void,而我们返回_

但是为什么编译得很好:

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

我们返回的是String,而不是Void,那么为什么编译器不抱怨呢?

【问题讨论】:

  • 我也很好奇。希望@matt 能解释一下……?
  • 输入参数是一个返回something-&gt;())的函数。它知道 void 函数不会返回something,所以它会抱怨。但是第二个函数返回something,一个字符串。这样就通过了参数检查。让回报成为你想要的东西是你的责任。
  • (Int) -&gt; () 是一个闭包,它接受Int 并返回Void,不是吗? ericasadun.com/2015/05/11/swift-vs-voidVoid 与“无”不一样吗?我也可以完全注释掉返回并编译...

标签: ios swift reactive-cocoa reactive-cocoa-4


【解决方案1】:

_ 不是什么都没有。它是一个模式,或者是可以匹配任何东西的模式的一部分。它也可以用在赋值语句中,表明你不关心结果。

_ = foo()  // Ignore result returned from foo

在你的闭包中,如果你想返回nothing,那么:

return

如果您处于关闭的末尾,则完全省略返回。

如果你返回_,Swift 就无法确定你的闭包的签名。您可以通过以下方式证明这一点:

let bar = { return _ }  // Unable to infer closure return type in current context

如果您删除 _,它可以正常编译,因为 bar 变成了 () -&gt; ()

如果您尝试从函数返回 _,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 期待一个 (Int) -&gt; () 闭包,但我们传递了一个 (Int) -&gt; String 闭包。而且它有效...

但是,如果您取消注释 print(answer + 1) 行,return "" 则会导致错误:

void 函数中的意外非 void 返回

【讨论】:

  • 谢谢...但是(Int -&gt; ()) 表示返回Void 的闭包,不是吗?在这种情况下,为什么返回 String 不是编译器错误?看我上面的例子......
  • 我没有完整的答案,但请查看我的编辑以了解正在发生的事情。
猜你喜欢
  • 2015-01-31
  • 1970-01-01
  • 2017-06-07
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
相关资源
最近更新 更多