对会员' print'的模棱两可的提及 - (Swift关闭范围?)

时间:2015-10-17 10:13:51

标签: swift closures

编译:

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 = ...

那为什么呢?

2 个答案:

答案 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" ) }

然后您可能会注意到ab未使用,请将其替换为_

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类型的参数,它会忽略并打印   “成功”