编译:
let s = SignalsService()
s.addListener( "key", callback: { a, b in print( "success" ) } )
这不是:
let s = SignalsService()
let cb = { a, b in print( "success" ) }
s.addListener( "key", callback: cb )
在Ambiguous reference to member 'print'
行投掷错误let cb = ...
。
那为什么呢?
答案 0 :(得分:9)
在
s.addListener( "key", callback: { a, b in print( "success" ) } )
编译器可以从上下文推断闭包的类型,
即从addListener()
方法的类型。如果那个方法是
例如声明为
func addListener(key : String, callback: (Int, Int) -> Void)
然后编译器可以推断出参数
{ a, b in print( "success" )
是一个关闭,需要两个Int
参数并返回Void
。
在
let cb = { a, b in print( "success" ) }
没有这样的上下文,因此编译器无法知道
封闭的类型。返回类型可以推断为
Void
因为闭包由一个表达式组成,
但你必须指定参数的类型,例如
let cb = { (a : Int, b : Int) in print( "success" ) }
答案 1 :(得分:2)
扩展@ MartinR的优秀答案。
Swift需要能够推断cb
类型为(Int, Int)->()
,或者您可以明确设置类型:
let cb: (Int, Int)->() = { a, b in print( "success" ) }
然后您可能会注意到a
和b
未使用,请将其替换为_
:
let cb: (Int, Int)->() = { _ in print( "success" ) }
当函数接受2个参数时,为什么我们可以使用单个_
?在这种情况下,Swift知道有2个参数,所以_
采用包含所有参数的元组的位置。它取代了(_, _)
。
你可以使用_
和@ MartinR的回答:
let cb = { (_:Int, _:Int) in print( "success" ) }
或者你可以这样写:
let cb = { (_:(Int, Int)) in print( "success" ) }
可以理解为:
cb
接受两个Int
类型的参数,它会忽略并打印 “成功”