我无法理解为什么这个有效:
var arr = [4,5,6,7]
arr.map() {
x in
return x + 2
}
虽然这不是
arr.map() {
x in
var y = x + 2
return y
}
有错误
游乐场执行失败:MyPlayground.playground:13:5:错误: 无法调用地图'使用类型'((_) - > _)'的参数列表 arr.map(){
答案 0 :(得分:5)
Swift can't infer type every time. Even though it should see that y = x + 2
means y
is an Int
too. My guess is that Swift parses the closure in a certain order that makes it not aware of the return type ahead of time in your case.
This works:
arr.map() {
x -> Int in
var y = x + 2
return y
}
答案 1 :(得分:5)
这里的问题是有错误信息。通常,当您看到类似cannot invoke .. with ...
的内容时,这意味着编译器的类型推断尚未起作用。
在这种情况下,您已经遇到了闭包中推理的一个限制。 Swift只能推断出单语句闭包的类型,而不是多语句闭包。在你的第一个例子中:
arr.map() {
x in
return x + 2
}
实际上只有一个陈述:return x + 2
。但是,在第二个:
arr.map() {
x in
var y = x + 2
return y
}
有一个赋值语句(var y = x + 2
),然后返回。所以这个错误有点误导:它并不意味着你不能用这种类型的论证调用map()"它意味着什么是"我可以"我能& #39;弄清楚x或y是什么类型"。
顺便说一下,在单语句闭包中,还有另外两个可以推断出来的东西。退货声明:
arr.map() {
x in
x + 2
}
变量名本身:
arr.map() { $0 + 2 }
但是,它会产生相同的编译代码。所以你选择的是一个真正的品味问题。 (例如,虽然我认为推断的return
看起来干净且易于阅读,但我并不像$0
那样,所以我通常总是{{1}或者某种东西,即使对于非常短的闭包。显然,它取决于你。)
最后一件事:因为这只是语法上的东西,值得注意的是x in
也不需要:
()
正如@MartinR指出的那样,编译器也可以从外部上下文中推断出一些类型:
arr.map { x in x + 2 }
值得记住的是。 (it seems that the "one-statement" rule only applies when there's no other type info available)