什么是闭包(Closure)?
2016-02-09 17:15
232 查看
http://www.vaikan.com/what-is-a-closure/
这个问题是在最近一次英格兰Brighton ALT.NET Beers活动中提出来的。我发现,如果不用代码来演示,你很难单用话语把它解释清楚,所以,在这里,我打算用C#来解释一下什么是闭包(closures)。维基百科上说:
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
所以,一个闭包就是一个“捕获”或“携带”了其被生成的环境中、所属的变量范围内所引用的所有变量的函数。的确,很难描述,但当你看完了这些代码后,你就很容易理解了。
这里我们首先定义了一个变量“x”,值为1。然后我们定义了一个匿名函数(一个lambda表达式)赋给类型Action。Action没有参数,没有返回值,但如果你观察“action”里的定义,你会发现它使用了“x”变量。这是变量是被action“捕获”或“携带”的,自动被添加到了action的运行环境中了。
当我们执行action时,它输出了我们预期的结果。请注意,当我们执行时,原始的“x”此时已经脱离了它当初的变量环境,但它仍然能用。
当你在代码调试器(debugger)里观察“action”时,会发现很有趣的事情。我们可以看到,C#编译器为我们创建了一个Target类,里面封装了x变量:
查看图片
闭包(和higher order functions)都是非常有用的东西。如果你曾经开发过稍微复杂一点的Javascript程序,你可能就会知道,这个东西可以被当成很多面向对象特征的替代品,就像C#那样。前不久我还在C#里写了一个例子来验证这种想法。
习惯性的,John Skeet给了闭包一个更详细的描述。更详细的信息请查看《深入解析C#》里的这一章。里面还介绍了你在闭包里会经常会遇到的一些错误。
这个问题是在最近一次英格兰Brighton ALT.NET Beers活动中提出来的。我发现,如果不用代码来演示,你很难单用话语把它解释清楚,所以,在这里,我打算用C#来解释一下什么是闭包(closures)。维基百科上说:
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
所以,一个闭包就是一个“捕获”或“携带”了其被生成的环境中、所属的变量范围内所引用的所有变量的函数。的确,很难描述,但当你看完了这些代码后,你就很容易理解了。
var x = 1; Action action = () => { var y = 2; var result = x + y; Console.Out.WriteLine("result = {0}", result); }; action();
这里我们首先定义了一个变量“x”,值为1。然后我们定义了一个匿名函数(一个lambda表达式)赋给类型Action。Action没有参数,没有返回值,但如果你观察“action”里的定义,你会发现它使用了“x”变量。这是变量是被action“捕获”或“携带”的,自动被添加到了action的运行环境中了。
当我们执行action时,它输出了我们预期的结果。请注意,当我们执行时,原始的“x”此时已经脱离了它当初的变量环境,但它仍然能用。
当你在代码调试器(debugger)里观察“action”时,会发现很有趣的事情。我们可以看到,C#编译器为我们创建了一个Target类,里面封装了x变量:
查看图片
闭包(和higher order functions)都是非常有用的东西。如果你曾经开发过稍微复杂一点的Javascript程序,你可能就会知道,这个东西可以被当成很多面向对象特征的替代品,就像C#那样。前不久我还在C#里写了一个例子来验证这种想法。
习惯性的,John Skeet给了闭包一个更详细的描述。更详细的信息请查看《深入解析C#》里的这一章。里面还介绍了你在闭包里会经常会遇到的一些错误。
相关文章推荐
- hdu 5623 KK's Number dp 博弈
- Android Material Design theme
- 设置交叉编译环境
- 11.IDA-this指针
- HTML5 Canvas之填充样式
- linux系统分区
- 数据输入输出加速
- 【小白的CFD之旅】04 任务
- JBoss 6.1安装配置问题
- JBoss 6.1安装配置问题
- C#成神之路<16> C#泛型
- Android中Textview超链接实现方式
- 【慕课笔记】U3 继承 第7节 JAVA中的Object类(二)
- 您这个问题并没有什么意义——比起怀疑自己,向前迈出一步才是更为重要的(三个解决方案)
- Notepad++ c编译环境 64
- C++大数模版
- java中成员变量和局部变量
- HDU 1081 To The Max(动态规划)
- 一个android文本比对app的实现(四)--Hirschberg文本比对算法
- Python实例一个类背后发生了什么