IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

什么是闭包(Closure)?

外刊IT评论 2011-08-14 15:51:35 累计浏览 3,839 次
本机暂存
本文是从 What is a Closure? 这篇文章翻译而来。

    这个问题是在最近一次英格兰Brighton ALT.NET Beers活动中提出来的。我发现,如果不用代码来演示,你很难单用话语把它解释清楚,所以,在这里,我打算用C#来解释一下什么是闭包(closures)。维基百科上说

    在计算机科学中,闭包�-losure)是词法闭包(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的运行环境中了。

    当我们执行acton时,它输出了我们预期的结果。请注意,当我们执行时,原始的“x”此时已经脱离了它当初的变量环境,但它仍然能用。

    当你在代码调试器(debugger)里观察“action”时,会发现很有趣的事情。我们可以看到,C#编译器为我们创建了一个Target类,里面封装了x变量:

    closure_in_debugger

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

    习惯性的,John Skeet给了闭包一个更详细的描述。更详细的信息请查看《深入解析C#》里的这一章。里面还介绍了你在闭包里会经常会遇到的一些错误。

同分类推荐文章

  1. 科技爱好者周刊(第 401 期):如何赚到10亿美元 (2026-06-26 08:05:38)
  2. 如何做决策 - 从 Go 的一个 issue 说起 (2026-06-26 08:00:00)
  3. Seven Player:Windows上播放115网盘视频的增强工具 (2026-06-09 00:06:47)

查看更多 开发者 文章 →

建议继续学习

  1. .NET 还是 Java? (累计阅读 5,655)
  2. JavaScript是Web的汇编语言(一):语义Web已死! (累计阅读 5,446)
  3. 为什么国内还有那么多网站使用.NET架构? (累计阅读 5,243)
  4. 理解Javascript的闭包 (累计阅读 4,884)
  5. Google+开发团队分享经验 (累计阅读 4,645)
  6. C#和C++混合编程的一些tips (累计阅读 4,434)
  7. JavaScript的闭包问题 (累计阅读 4,389)
  8. 通过HttpListener实现轻量级Web服务器[原创] (累计阅读 4,219)
  9. 设计模式速查手册-创建型 (累计阅读 3,922)
  10. 闭包漫谈(从抽象代数及函数式编程角度) (累计阅读 3,863)