Swift 闭包和 First-Class 函数有什么区别?

Swift any difference between Closures and First-Class Functions?

Apple 在 Swift 文档中这样说:

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.

我以为是First-class functions

的定义

他们也这么说:

Closures can capture and store references to any constants and variables from the context in which they are defined. This is known as closing over those constants and variables. Swift handles all of the memory management of capturing for you.

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

我是不是误会了什么?还是 Apple 调用闭包和 first-class 函数闭包?

我写了这个示例代码,只是想知道我写的评论是否正确?

// '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()

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

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

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

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

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

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

函数可以在声明它们的上下文中捕获变量,并且 "A combination of a function and an environment of captured variables is called - closure" more

这里是Swift中闭包和第一个class函数的简单解释:

  1. 函数首先是class对象,它们可以赋值给变量,可以作为参数传递,也可以返回

  2. 在Swift中有两种定义函数的方法:一种是使用func关键字,另一种是使用'closure expressions'——(并不意味着闭包)。例如

    func f() { print("nothing") }
    
    let a = f // cannot use parentheses here
    
    // or using closure expression:
    let a = { () -> void in print("nothing") }
    
  3. 最后直接回答你的问题:函数可以在声明的上下文中捕获变量,"A combination of a function and an environment of captured variables is called - closure" 例如

    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 为闭包,因为它捕获了一个变量。

这些概念是正交的。它们没有直接关系;它们是关于 Swift.

中函数的两个事实
  • 函数是first-class。这意味着它们可以传递——作为变量赋值,作为参数传入函数参数,作为结果传出函数。

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

这是一个例子(来自游乐场):

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

思考函数multiplier:

  • 事实上 multiplier 可以作为函数 multiplierMaker 的结果返回,并分配给 g,并且它有一个明确定义的type (Int) -> (Int), 是因为函数是 first-class.

  • 事实是,当将 10 传递给 multiplierMaker 时,生成的 multiplier 函数会将其参数乘以 10,即使分配给 g 并调用后来,是因为函数是 closures.

(请注意,这 与匿名函数无关 。所有让您相信闭包与匿名函数有关的答案或陈述都是错误的。没有匿名函数这个例子中的函数。一个匿名函数一个闭包,但这只是因为所有函数都是闭包。)