zoukankan      html  css  js  c++  java
  • 什么是闭包

    何为闭包?

    引用维基上面的说法,闭包是词法闭包的简称,就是引用了自由变量的函数,这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
    下面就自己熟悉的语言都来一种闭包。

    C#:

    1 var x = 1;
    2 Action action = () =>
    3 {
    4   var y = 2;
    5   var result = x + y;
    6   Console.Out.WriteLine("result = {0}", result);
    7 };
    8 action();

    在action()执行的时候就引用了外界的变量,形成了闭包。仔细观察action的定义,你会发现它使用了“x”变量。这是变量是被action“捕获”或“携带”的,自动被添加到了action的运行环境中了。当你在debug的时候,观察“action”时,会发现很有趣的事情。我们可以看到,C#编译器为我们创建了一个Target类,里面封装了x变量,如下图所示:

    Python:

    1 def line_conf():
    2   b = 15
    3   def line(x):
    4     return 2*x+b
    5   return line # return a function object
    6 
    7 b = 5
    8 my_line = line_conf()
    9 print(my_line(5)) 

    在上面的代码中,返回的line函数携带了外界变量b,也就构成了最简单的闭包。在上面的代码中,最终会打印出25,而不是15,这是为什么呢?这是因为line在做为函数返回的时候,line中已经包括b的取值,也就是说,line所参照的b值是函数对象定义时可供参考的b值,而不是使用时的b值。

    在python中,环境变量取值被保存在函数对象的__closure__属性中。比如下面的代码:

    1 print(my_line.__closure__)
    2 print(my_line.__closure__[0].cell_contents)

    javascript:

    javascript跟python有相同之处,因为在它们当中,函数都是做为一等公民而存在。此处就不多说了,可以参考Mgen写的这篇文章,另外在这文章中,也例举了c#跟javascript的不同。

    objective-c:

    在苹果的开发语言中,block就是一个明显的例子,可以自行参考,不再啰嗦。

  • 相关阅读:
    CentOS7.6下 MariaDB的MHA 集群搭建(一)
    Mariadb10.4 集群压力测试(一)
    Galera 核心参数详解(一)
    Mariadb10.4+ ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
    手动打造一个弹窗程序
    IAT HOOK
    进制的本质
    基于数组越界的缓冲区溢出
    函数调用堆栈图-c语言
    算法之二分查找(上)-c语言实现
  • 原文地址:https://www.cnblogs.com/xwang/p/3545718.html
Copyright © 2011-2022 走看看