美文网首页
闭包的思想

闭包的思想

作者: doob_9117 | 来源:发表于2019-07-12 12:03 被阅读0次

思考一个问题:
如何能够在运行的时候生成或者改变一个函数?
比如在一个函数外部修改一个变量就能改变这个函数的行为?

于是一个称之为闭包的东西出现了。
闭包:函数和引用的外部变量一起构成一个闭包。

✳注意:如果没有上述目的,不要引用函数外部的变量。把它作为参数传入你的函数。否则你很有可能因此引入意想不到的bug。

如何实现闭包?
下面是golang的实现

以下引自https://hitzhangjie.github.io/jekyll/update/2018/05/19/golang-function-closure%E5%AE%9E%E7%8E%B0%E6%9C%BA%E5%88%B6.html

  1. 假如闭包定义后立即被调用 因为只会被使用一次,所以应该力图避免闭包对象的内存分配操作,那怎么优化一下呢,以下面的示例代码为例。
func(a int) {
    println(byval)
    byref++
}(42)

上面的闭包将被转换为简单函数调用的形式:

func(byval int, &byref *int, a int) {
    println(byval)
    (*&byref)++
}(byval, &byref, 42)

注意看函数原型的变化,原来闭包里面捕获的变量都被转换成了通过函数参数来供值:

因为println操作不涉及对byval变量的修改操作,所以是按值捕获;
而byref++涉及到对捕获变量的修改,所以是按引用捕获,对于按引用捕获的变量会进行特殊处理,golang编译器会在编译时将按引用捕获的变量名byref转换成“&byref”,同时将其类型转换成pointer类型,捕获变量对应的写操作也会转换为通过pointer来操作。
2) 假如闭包定以后并不是立即调用 闭包定义后不是立即使用,而是后续调用,这种情况下同一个闭包可能调用多次,这种情况下就需要创建闭包对象,如何实现呢?

如果变量是按值捕获,并且该变量占用存储空间小于2*sizeof(int),那么就通过在函数体内创建局部变量的形式来shadow捕获的变量,相比于通过引用捕获,这么做的好处应该是考虑到减少引用数量、减少逃逸分析相关的计算。
如果变量是按引用捕获,或者按值捕获但是捕获的变量占用存储空间较大(拷贝到本地做局部变量代价太大),这种情况下就将捕获的变量var转换成pointer类型的“&var”,并在函数prologue阶段将其初始化为捕获变量的值。

相关文章

  • 闭包的思想

    思考一个问题:如何能够在运行的时候生成或者改变一个函数?比如在一个函数外部修改一个变量就能改变这个函数的行为? 于...

  • javascript闭包

    今天,看到javascript闭包,仔细想想,闭包是一种思想,一种技巧,其他语言应该也可以实现闭包的功能。 为什么...

  • 闭包

    浅谈 python 的闭包思想 首先 python的闭包使用方法是:在方法A内添加方法B,然后return 方法B...

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • Python闭包

    闭包 = 环境变量 + 函数 调用闭包内部的环境变量 闭包的经典误区 闭包与非闭包实现人类走路 非闭包 闭包

  • (9) python之闭包

    闭包闭包 = 函数 + 环境变量(函数定义的时候) 一个最简单的闭包 闭包不受外部变量影响 非闭包 闭包 闭包 只...

  • javascript闭包详解

    跟我念 bi 闭 bao包 ,闭包的闭,闭包的包。。 闭包的简介 在计算机科学中,闭包(英语:Closure),又...

  • 闭包,闭包,闭包

    1、这家伙到底是什么? 网上关于这个的讨论的太多了太多了,有各种的举例子,但是大部分还在寻找这个答案的小伙伴对于变...

  • Gradle开发-Groovy闭包

    # 闭包 闭包的基础知识 闭包的使用 闭包 this,owner,delegate 的理解 总结 ## 闭包的基础...

网友评论

      本文标题:闭包的思想

      本文链接:https://www.haomeiwen.com/subject/rmdekctx.html