闭包和一级功能之间有什么区别吗?

时间:2023-01-26 21:10:15

In the Swift documentation Apple says this:

在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.

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

Which I thought was the definition of First-class functions

我认为第一流函数的定义是什么

And they also say this:

他们还说

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.

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

I thought this was the definittion of closures while the other defitintion was for first-class functions, but Apple seems the put them together and call it closure.

我认为这是闭包的定义,而另一个缺陷是为了一流的功能,但苹果似乎把它们放在一起,并称之为闭包。

Have I misunderstood something? or are Apple calling closures and first-class functions closures?

我误解了什么?或者,苹果公司(Apple)将闭包和一流功能称为闭包?

I've written this example code, and just wanna know if I'm right in the written comments?

我写了这个例子代码,想知道我写的注释对不对?

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

3 个解决方案

#1


5  

These notions are orthogonal. They are not directly related; they are two facts about functions in Swift.

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

  • Functions are first-class. This means they can be passed around — assigned as variables, passed into function parameters as arguments, and passed out of functions as results.

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

  • Functions are closures. This means that, at the point of definition, they capture the environment referred to inside the function body but declared outside the function body.

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

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.

    乘数可以作为函数multiplierMaker的结果返回,并分配给g,并且它有一个定义良好的类型(Int)——> (Int),这是因为函数是一流的。

  • 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.

    当10传递给multiplierMaker时,产生的乘数函数将其参数乘以10,即使是分配给g并在稍后调用时,也是因为函数是闭包的。

(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.)

(请注意,这与匿名函数无关。所有导致您认为闭包与匿名函数有关的答案或语句都是错误的。本例中没有匿名函数。匿名函数是闭包,但只是因为所有函数都是闭包。

#2


8  

A First Class Function is a language feature that allows a function that can be assigned to a variable and passed around as if it were any other kind of data. Closures, lambdas and anonymous functions are all "First class functions".

第一类函数是一种语言特性,它允许将函数分配给一个变量,并将其作为任何其他类型的数据进行传递。闭包、lambdas和匿名函数都是“第一类函数”。

Anonymous Functions, also called Lambda functions, are functions that don't have a name (such as the way a(ch:) has a name). Because they don't have a name, the only way to use them is by storing them in a variable or passing them in as arguments (parameters are essentially variables). Thus all Anonymous functions are also First Class Functions.

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

Closures are first class functions that capture the state around them. They can be anonymous, or have a name. Named closures are just your regular func functions.

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

a(ch:) is a higher order function, correct.

a(ch:)是一个高阶函数,对。

ch is a First Class Function (as it's stored in a variable), a Lambda (synonymous with FCF) and possibly also a closure, depending on whether or not its body references any external variables.

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

In the case of a(ch:) being called with that block, ch is a closure, because it's capturing num.

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

#3


4  

Functions can capture variables in the context they were declared in, and "A combination of a function and an environment of captured variables is called - closure" more

函数可以在声明的上下文中捕获变量,“一个函数和一个捕获变量的环境的组合被称为-闭包”

Here is a simple explanation of closures and first class functions in Swift:

以下是Swift闭包和一级函数的一个简单解释:

  1. Functions are first class objects, they can be assigned to variables, they can be passed as arguments and can be returned

    函数是第一类对象,它们可以分配给变量,它们可以作为参数传递,也可以返回

  2. There are two ways of defining functions in Swift: one using the func keyword and using 'closure expressions' - (does not mean closures). e.g.

    在Swift中定义函数有两种方式:一种使用func关键字,另一种使用“闭包表达式”(不表示闭包)。如。

    func f() { print("nothing") }
    
    let a = f // cannot use parentheses here
    
    // or using closure expression:
    let a = { () -> void in print("nothing") }
    
  3. And finally the direct answer to your question: Functions can capture variables in the context they were declared in, and "A combination of a function and an environment of captured variables is called - closure" e.g.

    最后,你的问题的直接答案是:函数可以在它们被声明的上下文中捕获变量,并且“一个函数的组合和一个被捕获变量的环境被称为闭包”。

    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
    

    Now we call f1 a closure because it captured a variable.

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

#1


5  

These notions are orthogonal. They are not directly related; they are two facts about functions in Swift.

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

  • Functions are first-class. This means they can be passed around — assigned as variables, passed into function parameters as arguments, and passed out of functions as results.

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

  • Functions are closures. This means that, at the point of definition, they capture the environment referred to inside the function body but declared outside the function body.

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

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.

    乘数可以作为函数multiplierMaker的结果返回,并分配给g,并且它有一个定义良好的类型(Int)——> (Int),这是因为函数是一流的。

  • 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.

    当10传递给multiplierMaker时,产生的乘数函数将其参数乘以10,即使是分配给g并在稍后调用时,也是因为函数是闭包的。

(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.)

(请注意,这与匿名函数无关。所有导致您认为闭包与匿名函数有关的答案或语句都是错误的。本例中没有匿名函数。匿名函数是闭包,但只是因为所有函数都是闭包。

#2


8  

A First Class Function is a language feature that allows a function that can be assigned to a variable and passed around as if it were any other kind of data. Closures, lambdas and anonymous functions are all "First class functions".

第一类函数是一种语言特性,它允许将函数分配给一个变量,并将其作为任何其他类型的数据进行传递。闭包、lambdas和匿名函数都是“第一类函数”。

Anonymous Functions, also called Lambda functions, are functions that don't have a name (such as the way a(ch:) has a name). Because they don't have a name, the only way to use them is by storing them in a variable or passing them in as arguments (parameters are essentially variables). Thus all Anonymous functions are also First Class Functions.

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

Closures are first class functions that capture the state around them. They can be anonymous, or have a name. Named closures are just your regular func functions.

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

a(ch:) is a higher order function, correct.

a(ch:)是一个高阶函数,对。

ch is a First Class Function (as it's stored in a variable), a Lambda (synonymous with FCF) and possibly also a closure, depending on whether or not its body references any external variables.

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

In the case of a(ch:) being called with that block, ch is a closure, because it's capturing num.

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

#3


4  

Functions can capture variables in the context they were declared in, and "A combination of a function and an environment of captured variables is called - closure" more

函数可以在声明的上下文中捕获变量,“一个函数和一个捕获变量的环境的组合被称为-闭包”

Here is a simple explanation of closures and first class functions in Swift:

以下是Swift闭包和一级函数的一个简单解释:

  1. Functions are first class objects, they can be assigned to variables, they can be passed as arguments and can be returned

    函数是第一类对象,它们可以分配给变量,它们可以作为参数传递,也可以返回

  2. There are two ways of defining functions in Swift: one using the func keyword and using 'closure expressions' - (does not mean closures). e.g.

    在Swift中定义函数有两种方式:一种使用func关键字,另一种使用“闭包表达式”(不表示闭包)。如。

    func f() { print("nothing") }
    
    let a = f // cannot use parentheses here
    
    // or using closure expression:
    let a = { () -> void in print("nothing") }
    
  3. And finally the direct answer to your question: Functions can capture variables in the context they were declared in, and "A combination of a function and an environment of captured variables is called - closure" e.g.

    最后,你的问题的直接答案是:函数可以在它们被声明的上下文中捕获变量,并且“一个函数的组合和一个被捕获变量的环境被称为闭包”。

    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
    

    Now we call f1 a closure because it captured a variable.

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