10

在 Swift 文档中,Apple 是这样说的:

闭包是可以在代码中传递和使用的独立功能块。Swift 中的闭包类似于 C 和 Objective-C 中的块以及其他编程语言中的 lambda。

我认为这是一流功能的定义

他们也这样说:

闭包可以从定义它们的上下文中捕获和存储对任何常量和变量的引用。这被称为关闭这些常量和变量。Swift 为您处理所有捕获的内存管理。

我认为这是闭包的定义,而另一个定义是针对一流函数的,但苹果似乎将它们放在一起并称之为闭包。

我误解了什么吗?还是苹果调用闭包和一流的函数闭包?

我已经编写了这个示例代码,只是想知道我在书面评论中是否正确?

// 'a' takes a first class function, which makes 'a' a higher order function
func a(ch: () -> Void){
    print("Something")
    ch()                // 'ch' is a first class function
    print("Ended")
}

func closureFunc(){
    var num = 2
    a({
        // access to 'num' is possible by closures
        num = num*2
        print(num)
    })
}

closureFunc()
4

3 回答 3

9

First Class Function是一种语言功能,它允许将函数分配给变量并像传递任何其他类型的数据一样传递。闭包、lambda 和匿名函数都是“一流的函数”。

匿名函数,也称为Lambda函数,是没有名称的函数(例如有a(ch:)名称的方式)。因为它们没有名称,所以使用它们的唯一方法是将它们存储在变量中或将它们作为参数传递(参数本质上是变量)。因此,所有匿名函数也是一等函数。

闭包是捕获它们周围状态的一流函数。他们可以是匿名的,也可以有名字。命名闭包只是你的常规func函数​​。

a(ch:)是高阶函数,正确。

ch是一个第一类函数(因为它存储在一个变量中),一个 Lambda(与 FCF 同义),也可能是一个闭包,这取决于它的主体是否引用任何外部变量。

a(ch:)使用该块调用的情况下,ch是一个闭包,因为它正在捕获num

于 2016-05-30T19:25:26.393 回答
6

这些概念是正交的。它们没有直接关系;它们是关于 Swift 中函数的两个事实。

  • 函数是一流的。这意味着它们可以被传递——作为变量赋值,作为参数传递给函数参数,作为结果传递给函数。

  • 函数是闭包。这意味着,在定义时,它们捕获了在函数体内部引用但在函数体外部声明的环境。

Here is an example (from a playground):

func multiplierMaker(i:Int) -> (Int) -> (Int) {
    func multiplier(ii:Int) -> (Int) {
        return ii*i
    }
    return multiplier
}
let g = multiplierMaker(10)
g(2) // 20

Think about the function multiplier:

  • The fact that multiplier can be returned as the result of the function multiplierMaker, and assigned to g, and that it has a well-defined type (Int) -> (Int), is because functions are first-class.

  • The fact that, when 10 is passed into multiplierMaker, the resulting multiplier function multiplies its parameter by 10, even when assigned to g and called later, is because functions are closures.

(Notice that this has nothing to do with anonymous functions. All answers or statements leading you to believe that closures have to do with anonymous functions are wrong. There are no anonymous functions in this example. An anonymous function is a closure, but only because all functions are closures.)

于 2016-05-30T20:11:57.983 回答
4

函数可以在声明它们的上下文中捕获变量,并且“函数和捕获变量的环境的组合称为 - 闭包”更多

下面是对 Swift 中的闭包和第一类函数的简单解释:

  1. 函数是第一类对象,可以赋值给变量,可以作为参数传递,也可以返回

  2. 在 Swift 中定义函数有两种方法:一种使用 func 关键字和使用“闭包表达式” - (并不意味着闭包)。例如

    func f() { print("nothing") }
    
    let a = f // cannot use parentheses here
    
    // or using closure expression:
    let a = { () -> void in print("nothing") }
    
  3. 最后是您问题的直接答案:函数可以在声明它们的上下文中捕获变量,并且“函数和捕获变量的环境的组合被称为 - 闭包”,例如

    func f() -> ()->()
    {
        var c = 0 // local var
    
        func innerf()
        {
            c += 1 // c is now captured 
        }
    
        return innerf
    } // normally c would be released here. but since its used in innerf(), it will stay
    
    let f1 = f
    

    现在我们称 f1 为闭包,因为它捕获了一个变量。

于 2016-05-30T19:54:15.990 回答