设为首页收藏本站

Scripts 学盟

 找回密码
 加入学盟

QQ登录

只需一步,快速开始

查看: 1068|回复: 3
打印 上一主题 下一主题

什么是闭包(Closure)? [复制链接]

Rank: 8Rank: 8

风雨相伴

跳转到指定楼层
1#
Snail 实名认证  发表于 2011-11-2 12:32:37 |只看该作者 |倒序浏览
本文是从外刊IT评论转载
What is a Closure? 这篇文章翻译而来。


这个问题是在最近一次英格兰Brighton ALT.NET Beers活动中提出来的。我发现,如果不用代码来演示,你很难单用话语把它解释清楚,所以,在这里,我打算用C#来解释一下什么是闭包(closures)。维基百科上说:
  1. 在[url=http://www.aqee.net/wiki/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6]计算机科学[/url]中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
复制代码
所以,一个闭包就是一个“捕获”或“携带”了其被生成的环境中、所属的变量范围内所引用的所有变量的函数。的确,很难描述,但当你看完了这些代码后,你就很容易理解了。
  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();
复制代码
这里我们首先定义了一个变量“x”,值为1。然后我们定义了一个匿名函数(一个lambda表达式)赋给类型Action。Action没有参数,没有返回值,但如果你观察“action”里的定义,你会发现它使用了“x”变量。这是变量是被action“捕获”或“携带”的,自动被添加到了action的运行环境中了
当我们执行action时,它输出了我们预期的结果。请注意,当我们执行时,原始的“x”此时已经脱离了它当初的变量环境,但它仍然能用。
当你在代码调试器(debugger)里观察“action”时,会发现很有趣的事情。我们可以看到,C#编译器为我们创建了一个Target类,里面封装了x变量:

closure_in_debugger.png



闭包(和higher order functions)都是非常有用的东西。如果你曾经开发过稍微复杂一点的Javascript程序,你可能就会知道,这个东西可以被当成很多面向对象特征的替代品,就像C#那样。前不久我还在C#里写了一个例子来验证这种想法。

习惯性的,John Skeet给了闭包一个更详细的描述。更详细的信息请查看《深入解析C#》里的这一章。里面还介绍了你在闭包里会经常会遇到的一些错误。
分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
分享分享0 收藏收藏0
命运的手,推我向前!何处是停歇!

Rank: 8Rank: 8

2#
那个谁 发表于 2011-11-3 08:30:02 |只看该作者

使用道具 举报

管理员

超级大菜鸟

Rank: 9Rank: 9Rank: 9

3#
混混@普宁.中国 实名认证  发表于 2011-11-4 21:08:51 |只看该作者

使用道具 举报

Rank: 8Rank: 8

4#
momo 发表于 2012-1-19 10:35:15 |只看该作者
过了爱做梦的年纪
轰轰烈烈不如平静

使用道具 举报

您需要登录后才可以回帖 登录 | 加入学盟

手机版|Scripts 学盟   

GMT+8, 2025-6-13 15:12 , Processed in 1.153000 second(s), 16 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部