作为对 Ruby 的敬意,我一直在玩 Int 的扩展,它允许我编写如下有用的代码:
3.times { println("I keep holding on") }
这很好用,这是扩展:
extension Int {
func times(fn: () -> ()) {
for i in 1...self {
fn()
}
}
}
现在,我想将迭代次数传递给闭包,所以我向扩展添加了一个 2nd times() 函数:
extension Int {
func times(fn: (iteration: Int) -> ()) {
for i in 1...self {
fn(iteration: i)
}
}
}
可以这样调用:
5.times { (i: Int) -> () in println("Year \(i)") }
现在,根据 Swift 文档,
It is always possible to infer the parameter types and return type when passing a closure to a function as an inline closure expression. As a result, you never need to write an inline closure in its fullest form when the closure is used a function argument.
这听起来不错,因为这样我就可以省略参数和返回类型,即 (i: Int) -> ()
,而只需使用以下语法:
5.times { i in println("Year \(i)") }
但这会导致以下错误:Error: Ambiguous use of 'times'
这种调用我的 times()
函数的方式是否对编译器真的不明确?
最佳答案
这是模棱两可的。如果闭包的参数类型未知,则两种 .times()
方法都可以与给定的闭包表达式一起使用。
如果你只是写{ i in println("Year\(i)") }
,它只是一个接受任何类型参数的闭包。好吧,Swift 中的每一种函数类型都可以被视为采用一个参数:
- 您认为的零参数函数实际上采用一个类型为
()
(又名Void
)的参数,值为()
,这就是为什么类型被写成() -> something
- 你认为的多参数函数实际上接受一个元组类型的参数,一个所有“多个参数”的元组,这就是为什么类型被写成
(foo, bar) -> something
.
因此,基本上,您的闭包表达式,无需指定 i
的类型,可以推断为 Swift 中任何返回 Void
的函数类型。两个 .times()
方法采用的函数与此匹配——对于第一个 .times()
方法,它被推断为 () 类型的函数-> ()
,即 i
的类型为 ()
;对于第二个 .times()
方法,它被推断为 Int -> ()
类型的函数,即 i
的类型为 整数
。
关于ios - Swift 推断闭包参数之谜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25697615/