【问题标题】:Swift any difference between Closures and First-Class Functions?Swift 闭包和一流函数有什么区别?
【发布时间】:2016-09-28 15:33:12
【问题描述】:

Apple 在 Swift 文档中这样说:

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

我以为是First-class functions的定义

他们也这样说:

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

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

我是不是误会了什么?还是 Apple 调用闭包和一流的函数闭包?

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

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

【问题讨论】:

  • 一切看起来都不错——闭包可以获取它们之外的参数,包括self.(必须是明确的)。看看stackoverflow.com/questions/29022985/…
  • 如果您觉得您的问题已经得到满足,请接受其中一个答案

标签: swift closures first-class-functions


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • “闭包是匿名函数”不。所有函数都是 Swift 中的闭包。
  • 这就是答案!
【解决方案2】:

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

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

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

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

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,并且它具有明确定义的类型(Int) -> (Int),这是因为函数是 一流的。

  • 1234563 .

(请注意,这与匿名函数无关。所有导致您相信闭包与匿名函数有关的答案或陈述都是错误的。此示例中没有匿名函数。匿名函数闭包,但仅仅是因为所有函数都是闭包。)

【讨论】:

    【解决方案3】:

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

    这里简单解释一下 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 为闭包,因为它捕获了一个变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      • 2014-07-30
      • 1970-01-01
      • 2011-03-24
      • 2014-09-29
      • 1970-01-01
      • 2016-08-03
      相关资源
      最近更新 更多