我试图定义一个可以保存闭包的变量,并使用Swift的速记参数名称遇到一些困难。请使用以下代码段:
var returnAString: (String, String) -> String
returnAString = { return $0 }
这给了我编译错误 '(String,String)'不能转换为' String' 。当我修改闭包时返回一个带有第一个参数值的字符串,我在元组中返回两个参数值。
println(returnAString("1", "2")) // Prints "(1, 2)"
但是,如果我修改闭包以打印第二个参数,则按预期打印正确的参数。
returnAString = { $1 }
println(returnAString("1", "2")) // Prints "2"
我感觉我在这里做了一些有点傻事,但我无法找到解释为什么会这样做的原因。
答案 0 :(得分:9)
Closures § Shorthand Argument Names
速记参数名称
... 缩写参数名称的数量和类型将从预期的函数类型中推断出来。
看起来这是预期的行为。通过仅提供$0
,您推断(至少对系统而言)您想要一个元组。
这似乎只是使用$0
的特例。例如,以下内容无法编译。
var returnAString3: (String, String, String) -> String
returnAString3 = { return $1 }
无论如何修改。
returnAString3 = { return $1.0 } // still fails.
答案 1 :(得分:2)
类型推断将$0
视为元组而不是第一个参数,因为您没有使用第二个参数。
如果你只引用第二个参数,它可以正常工作:
returnAString = { $1; return $0 }
证明我所说的是正确的来自0x7fffffff的评论:
returnAString = { $0.0 }
表示获取$0
元组的第一个值并返回它。
答案 2 :(得分:0)
对于该语言,“多个参数”与作为元组的单个参数相同。由于仅使用$0
而不是$1
等,编译器首先猜测只有一个参数。并且该猜测始终有效,因为任何函数类型都可以被视为只有一个参数(可能是Void
,元组或其他)。