什么是闭包

闭包 Closures,最初接触大概是在看 Swift 文档的时候,但是似是而非,好像明白了,好像就没彻底明白,记得当时也查了一些资料,终究是没彻底弄清楚。

后来看 Kotlin 也谈到闭包,看下 Kotlin 里的定义:

A lambda expression or anonymous function (as well as a local function and an object expression) can access its closure, i.e. the variables declared in the outer scope.

Lambda 表达式或者匿名函数(以及局部函数和对象表达式) 可以访问其闭包,即在外部作用域中声明的变量。

好简洁啊,插个题外话,整个 Kotlin 文档的编排顺序,详细度都无法和 Swift 文档相比。

再来看看 Swift 的说明,它说闭包有三种形式:

  • Global functions are closures that have a name and do not capture any values. 全局函数是一个有名字但不会捕获任何值的闭包。
  • Nested functions are closures that have a name and can capture values from their enclosing function. 内嵌函数是一个有名字且能从其上层函数捕获值的闭包。
  • Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context. 闭包表达式是一个轻量级语法所写的可以捕获其上下文中常量或变量值的没有名字的闭包。

第一种全局函数,不捕获任何值,也没什么好说的,第二种内嵌函数,这是最常见的类型,第三种其实就是 lambda 表达式,也相当于内嵌函数。

之所以想起写这篇文章,是因为前几周在阅读《函数式编程思维》时,读到里面讲到闭包,突然感觉明白了。

书里说闭包是一种特殊的函数,暗地绑定了函数内部引用的全部变量。闭包在生成的时候,会把引用的变量全部圈到代码块的作用域里,封闭包围起来,故名『闭包』。

这里用 Swift 文档里的例子来说明

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

外部函数 makeIncrementer 的返回值类型是一个函数 incrementer,而 incrementer 函数本身并没有任何参数,runningTotal 和 amount 都是外部函数的。

当调用 makeIncrementer 返回一个函数时,依然可以调用这个返回的 incrementer 函数返回一个整数,因为 runningTotal 和 forIncrement 已经被它和自己绑定在一起了。每调用一次 runningTotal 的值就递增一个 forIncrement 的大小

// 获得一个闭包实例
let incrementByTen = makeIncrementer(forIncrement: 10)

// 连续调用三次
incrementByTen()
//return a value of 10
incrementByTen()
//return a value of 20
incrementByTen()
//return a value of 30

// 获得另一个闭包
let incrementBySeven = makeIncrementer(forIncrement: 7)
incrementBySeven()
// returns a value of 7

// 再次调用第一个闭包
incrementByTen()
// returns a value of 40

incrementBySeven 和 incrementByTen 互不影响。因为闭包的每个实例都保有自己的一份变量取值,包括私有变量

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 闭包(closure)是javascript的一大难点,也是它的特色。很多高级应用都要依靠闭包来实现。 1、变量作...
    乖乖果效36阅读 3,332评论 0 0
  • 闭包的使用在许多高级程序都能够有用到。 闭包就是一个函数引用另一个函数的变量,因为变量被引用着所以不会被回收,因此...
    南柯一i梦阅读 3,424评论 0 0
  • 如果不用代码来演示,你很难单用话语把它解释清楚 维基百科的解释 在计算机科学中,闭包(Closure)是词法闭包(...
    JacquesMayol阅读 4,276评论 0 0
  • 昨天晚上,打开简书,想写一些东西,老公喝了酒,话特别多,在我耳畔一直聒噪。我不能静下心来,也不能发火。只能一直敷衍...
    我是慕一阅读 1,612评论 2 2

友情链接更多精彩内容