ios - Swift 推断闭包参数之谜

标签 ios ruby swift

作为对 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/

相关文章:

ios - dequeueReusableCell 方法返回新的或可重用的对象?

ios - 具有多个 CollectionViewLayout 的单个 CollectionView。为什么布局困惑?

ruby-on-rails - 从 Ruby on Rails 开始。在指定要下载的版本时,Gemfile 和 gems 是如何工作的?

ruby - 如何使用 rbenv 在系统范围内安装 ruby

node.js - 使用 Node.js 服务器的 Firebase 云消息传递

ios - 为什么 recvfrom 方法的返回值是 4294967295 应该是 0 或 -1?

iphone - Facebook IOS SDK 3.1 - reauthorizeWithPublishPermissions?

ruby - Mechanize 带有后缀的选择 ID

ios - 将 HTML 字符串转换为 NSAttributedString 时运行 Archive 时崩溃

ios - 如何保存录制的音频 iOS?