由示例代码混淆,该代码向类型添加新的实例方法

时间:2016-07-21 13:05:39

标签: swift function extension-methods

以下代码段从official document复制,用于演示如何使用Extensions向现有类型添加方法。

extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()//what's going on here?
        }
    }
}

3.repetitions { //why I don't have to call as `repetitions()`
    print("Hello!")
}

问题:问题不是询问延长如何扩展。我对这段代码感到有点困惑,为什么它看起来像这样?为什么在函数体内使用task()?它来自哪里?对于行3.repetition,为什么不将其写为3.repetition()

非常感谢

2 个答案:

答案 0 :(得分:3)

repetitions是一个函数,它接受一个函数作为参数,并多次调用该函数。

要拨打repetitions,我们可以说(注意,这是Swift 3):

func sayHi() {
    print("Hello")
}
3.repetitions(task:sayHi)

但为什么要定义额外名称sayHi?相反,我们使用匿名函数:

3.repetitions(task:{print("Hello"})

但在这种情况下,我们可以在此repetitions调用中省略括号,并使用尾随语法:

3.repetitions{print("Hello")}

答案 1 :(得分:1)

  

为什么在函数体内使用task()?

task参数被定义为闭包又名匿名函数:

task: () -> Void

这表示该函数需要另一个函数作为参数,一个不带参数且不返回值的函数。

调用task()调用传入的函数。

  

对于3.repetition行,为什么不把它写成3.repetition()

搜索“尾随关闭语法”。如果Swift函数的最后一个参数是闭包,则可以将其附加到()参数列表之外的调用。 或者换句话说,这是完全相同的:

3.repetitions(task: {
  print("Hello!")
})

(是否必须使用task:作为关键字参数取决于您是使用Swift 2还是3。