Closure
From NeoWiki
(Difference between revisions)
m (→参考资料) |
|||
Line 21: | Line 21: | ||
这些概念上的解释很难理解,显然一个实际的例子更能说明问题。Lua语言的语法比较接近伪代码,我们来看一段Lua的代码: | 这些概念上的解释很难理解,显然一个实际的例子更能说明问题。Lua语言的语法比较接近伪代码,我们来看一段Lua的代码: | ||
+ | ;清单 1. 闭包示例1 | ||
+ | <source lang="lua"> | ||
+ | function make_counter() | ||
+ | local count = 0 | ||
+ | function inc_count() | ||
+ | count = count + 1 | ||
+ | return count | ||
+ | end | ||
+ | return inc_count | ||
+ | end | ||
+ | |||
+ | c1 = make_counter() | ||
+ | c2 = make_counter() | ||
+ | print(c1()) | ||
+ | print(c2()) | ||
+ | </source> | ||
Line 42: | Line 58: | ||
* [http://www.martinfowler.com/bliki/Closure.html Martin Fowler's Closure Intro]: Martin Fowler写的Closure简介,他的概念比较实用,但是未必准确,学院派恐会有微词。 | * [http://www.martinfowler.com/bliki/Closure.html Martin Fowler's Closure Intro]: Martin Fowler写的Closure简介,他的概念比较实用,但是未必准确,学院派恐会有微词。 | ||
* [http://www.infoq.com/cn/news/2007/09/catching-up-with-closures InfoQ:跟上Java闭包(Closure)的步伐]。 | * [http://www.infoq.com/cn/news/2007/09/catching-up-with-closures InfoQ:跟上Java闭包(Closure)的步伐]。 | ||
+ | |||
==关于作者== | ==关于作者== | ||
李文浩,东软集团(Neusoft)商用软件事业部资深软件工程师,主要技术兴趣包括编程语言、系统分析与软件构架等。 | 李文浩,东软集团(Neusoft)商用软件事业部资深软件工程师,主要技术兴趣包括编程语言、系统分析与软件构架等。 |
Revision as of 05:05, 19 November 2009
- 闭包的概念、形式与应用
李文浩, 资深软件工程师, Neusoft
- 随着硬件性能的提升以及编译技术和虚拟机技术的改进,一些曾被性能问题所限制的动态语言开始受到关注,Python、Ruby和Lua等语言都开始在应用中崭露头角。动态语言因其方便快捷的开发方式成为很多人喜爱的编程语言,伴随动态语言的流行,我们经常听到一个名词——闭包,很多人会问闭包是什么?闭包是用来做什么的?本文汇集了有关闭包的概念、应用及其在一些编程语言中的表现形式,以供参考。
Contents |
什么是闭包?
闭包并不是什么新奇的概念,它早在高级语言开始发展的年代就产生了。闭包(Closure)是词法闭包(Lexical Closure)的简称。对闭包的具体定义有很多种说法,这些说法大体可以分为两类:
- 一种说法认为闭包是符合一定条件的函数,比如在参考资源中这样定义闭包:闭包是在其词法上下文中引用了自由变量[1]的函数。
- 另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。比如在参考资源中就有这样的的定义:在实现深约束[2]时,需要创建一个能显式表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来的整体被称为闭包。
这两种定义在某种意义上是对立的,一个认为闭包是函数,另一个认为闭包是函数和引用环境组成的整体。虽然有些咬文嚼字,但可以肯定第二种说法更确切。闭包只是在形式和表现上像函数,但实际上不是函数。函数是一些可执行的代码,这些代码在函数被定义后就确定了,不会在执行时发生变化,所以一个函数只有一个实例。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。所谓引用环境是指在程序执行中的某个点所有处于活跃状态的约束所组成的集合。其中的约束是指一个变量的名字和其所代表的对象之间的联系。那么为什么要把引用环境与函数组合起来呢?这主要是因为在支持嵌套作用域的语言中,有时不能简单直接地确定函数的引用环境。这样的语言一般具有这样的特性:
- 函数是一阶值(First-class value),即函数可以作为另一个函数的返回值或参数,还可以作为一个变量的值。
- 函数可以嵌套定义,即在一个函数内部可以定义另一个函数。
这些概念上的解释很难理解,显然一个实际的例子更能说明问题。Lua语言的语法比较接近伪代码,我们来看一段Lua的代码:
- 清单 1. 闭包示例1
function make_counter() local count = 0 function inc_count() count = count + 1 return count end return inc_count end c1 = make_counter() c2 = make_counter() print(c1()) print(c2())
注释
参考资料
- Lua 5.1 Reference Manual: Lua 参考手册。
- Python Documentation: Python 参考手册。
- Ruby Documents: Ruby 在线文档。
- Harold Abelson and Gerald Jay Sussman with Julie Sussman, Structure and Interpretation of Computer Programs, MIT Press, 2nd edition, 1996: 著名的 MIT 教科书,有助于学习程序设计和 Scheme 语言,值得一看。
- J. Hughes, Why Functional Programming Matters. Computer Journal, 32(2):98–107, 1989.: 一篇论述函数式编程优势的奇文。
- William Clinger Richard Kelsey and Jonathan Rees (Editors), Revised 5 Report on the Algorithmic Language Scheme, Technical Report, 1998: Scheme语言规范第5版,现在已经出第6版了,在这里可以找到更多的信息。
- Dorai Sitaram Teach Yourself Scheme in Fixnum Days 2003: Scheme语言入门教程。
- Dave Thomas with Chad Fowler and Andy Hunt, Programming Ruby, Addison Wesley, 2nd edition, 2005.
- Michael L.Scott(裘宗燕 译),Programming Language Pragmatics(程序设计语言实践之路),电子工业出版社,2005。
- Martin Fowler's Closure Intro: Martin Fowler写的Closure简介,他的概念比较实用,但是未必准确,学院派恐会有微词。
- InfoQ:跟上Java闭包(Closure)的步伐。
关于作者
李文浩,东软集团(Neusoft)商用软件事业部资深软件工程师,主要技术兴趣包括编程语言、系统分析与软件构架等。