原著:Martin Fowler http://martinfowler.com/bliki/Closures.html
翻译:<liubin <at="">huangpuzhuang.com>
另外一片文章总结了各种语言实现的本文中的例子。
2004/11/23
本文地址:http://www.ruby-cn.org/articles/closures.html
随着人们对动态语言兴趣的日益浓厚,越来越多的人都遇到了闭包(Closures )和或块(Blocks)等概念。有着C/C++/Java/C#等语言背景的人因为这些语言本身没有闭包这个概念,所以可能不太了解闭包。本文将简单的介绍一下闭包的概念,那些有大量支持闭包语言编程经验的人也许觉得本文不会太有意思。 闭包的概念已经提出很长时间了。我第一次碰到这它是在smalltalk中,那时候还叫做块(blocks)。Lisp语言中用的很多。Ruby中也有同样的功能-这也是Ruby用户喜欢Ruby的一个原因。 本质上来说,一个闭包是一块代码,它们能作为参数传递给一个方法调用。我将通过一个简单的例子来阐述这个观点。假设我们有一个包含一些雇员对象的列表,然后我想列出职位为经理的员工,这样的员工可以通过IsManager判断。在C#里,我们可能会写出下面类似的代码: public static IList Managers(IList emps) { IList result = new ArrayList(); foreach(Employee e in emps) if (e.IsManager) result.Add(e); return result; } 在一种支持闭包的语言中,比如Ruby,我们可以这样写: def managers(emps) return emps.select {|e| e.isManager} end select是Ruby中定义的集合结构中的一个方法,它接受一个block,也就是闭包,作为一个参数。在Ruby中,闭包写在一对大括号中(不止这一种方法,另一种为do .. end)。如果这个块也接受参数,你可以将这些参数放到两个竖线之间。select方法循环迭代给定的数组,对每个元素执行给定的block,然后将每次执行block返回true的元素组成一个新的数组再返回。 现在,如果你是C程序员你也许要想,通过函数指针也可以实现,如果你是JAVA程序员,你可能回想我可以用匿名内类来实现,而一个C#者则会想到代理(delegate)。这些机制和闭包类似,但是它们和闭包之间有两个明显得区别。 第一个是形式上的不同(The first one is a formal difference)。闭包可以引用它定义时候可见的变量。看看下面的方法: def highPaid(emps) threshold = 150 return emps.select {|e| e.salary > threshold} end 注意select的block代码中引用了在包含它的方法中的局部变量,而其它不支持真正闭包的语言使用其它方法达到类似功能的方法则不能这样做。闭包还允许你做更有趣的事情,比如下面方法: def paidMore(amount) return Proc.new {|e| e.salary > amount} end 这个方法返回一个闭包,实际上它返回一个依赖于传给它的参数的闭包。我可以用一个参数创建一个这样的方法,然后再把它赋给另一个变量。 highPaid = paidMore(150) 变量 john = Employee.new john.salary = 200 print highPaid.call(john) 表达式 所以,闭包的第一个关键点是闭包是一段代码加上和定义它的环境之间的绑定(they are a block of code plus the bindings to the environment they came from)。这是闭包和函数指针等其它相似技术的不同点(java匿名内类可以访问局部变量,但是只有当这些内类是final的时候才行)。 第二个不同点不是定义形式的不同,但是也同样重要。(The second difference is less of a defined formal difference, but is just as important, if not more so in practice)。支持闭包的语言允许你用很少的语法去定义一个闭包,尽管这点可能不是很重要的一点,但我相信这点是至关重要的-这是使得人们能很自然的使用闭包的关键点。看看Lisp,Smalltalk和Ruby,闭包遍布各处-比其它语言中类似的使用多很多。绑定局部变量是它的特点之一,但我想最大的原因是使用闭包的语法和符号非常简单和清楚。 一个很好的相关例子是从Smalltalk程序员到JAVA程序员,开始时很多人,包括我,试验性的将在Smalltalk中使用闭包的地方在Java中使用匿名内类来实现。但结果使得代码变得混乱难看,所以我们不得不放弃。 我在Ruby经常使用闭包,但我不打算创建Proc对象,然后传来传去。大多数时间我用闭包来处理前面我提到的select等基于集合对象的方法。闭包另一个重要用途是'execute around method',比如处理一个文件: File.open(filename) {|f| doSomethingWithFile(f)} 这里open方法打开一个文件,然后执行给定的block,然后关闭它。这样处理非常方便,尤其是对事务(要求commit或者rollback),或者其它的你需要在处理结束时候作一些收尾处理的事情。我在我的xml文档转换中广泛使用这个优点。 闭包的这些用法显然远不如用Lisp语言的人遇到的多,即使我,在使用没有闭包支持的语言的时候,也会想念这些东西。闭包就像一些你第一眼见到觉得不怎么样的东西,但你很快就会喜欢上它们。 其它语言例子Joe Walnes在blog中提供了 closures in the next version of C#。这个例子是静态类型语言的,基于delegate,且需要delegate关键字。 更新: Ivan Moore提供类类似的 Python 的例子 更新: Vadim Nasardinov 让我知道了来自Guy Steeleled的 closures in Java 这个有趣的珍闻。 |
译者注:如你想知道上面例子中文件对象是怎么自己关闭的,请看http://blog.csdn.net/ruby_cn/archive/2004/11/23/192588.aspx,希望可以找到答案。翻译的不好,请多原谅。欢迎交流。括号之中的英语实在是不知如何很好翻译,所以保留了下来。
相关推荐
《重构——改善既有代码设计》是软件工程领域的一部经典著作,作者Martin Fowler,该书与《设计模式》被并称为软件工程的双雄。《重构》一书的主旨在于向读者展示重构的过程与方法,即通过一系列小的、有步骤的改变...
《重构 -改善既有代码的设计》是由美国著名软件开发专家Martin Fowler所著,由熊节翻译的一本经典IT著作。这本书深入探讨了重构这一关键的软件工程实践,旨在帮助开发者提升既有代码的质量和可维护性。重构是软件...
马丁·福勒(Martin Fowler)在其著作《Domain Specific Languages》中深入探讨了这一主题,该书由Addison-Wesley Professional出版社于2010年9月24日出版。本书提供了关于如何设计、实现和使用DSLs的全面指南,并...
Martin Fowler和《重构:改善既有代码的设计》(中文版)另几位作者清楚揭示了重构过程,他们为面向对象软件开发所做的贡献,难以衡量。《重构:改善既有代码的设计》(中文版)解释重构的原理(principles)和最佳实践...
Martin Fowler是重构领域中极具影响力的专家之一,他的著作《重构——改善既有代码的设计》被广泛认为是该领域的经典之作。这本书不仅传授重构的理论知识,还提供了丰富的实际案例和步骤指导,让读者可以将理论应用...
Java 8采用Martin Fowler的方法创建内部DSL(领域特定语言)是一种强大的编程技术,它允许我们构建高度定制且易于理解的代码。内部DSL是通过在已有的编程语言内部构造一种专用的语言来实现的,使得代码更贴近所要...
Martin Fowler名箸 Patterns of Enterprise Application Architec
UML2初学好书-(“UML Distilled”:Martin Fowler)-中英文合辑 EN::(UML Distilled) Third Edition(2003)--CHM格式 , zhTW:(UML 精华第三版) /物件模型语言标准简介---PDF格式 [物件模型语言标准简介初学好书-UML-2...
Martin Fowler的《分析模式》是一本在软件工程领域具有深远影响的书籍,尤其是对面向对象分析和设计的实践者。本书首次出版于1996年,是分析模式理论的奠基之作,作者马丁·福勒(Martin Fowler)是国际知名的软件...
重构,改善既有代码的设计(中文版,Martin Fowler 著).part03
### 分析模式-Martin Fowler #### 一、引言与概念模型 《分析模式》是IT界大师Martin Fowler的一部经典著作。本书旨在为复杂的业务分析领域提供一系列实用且易于理解的设计模式,帮助读者更好地理解和解决实际问题...
Martin Fowler和《重构:改善既有代码的设计》(中文版)另几位作者清楚揭示了重构过程,他们为面向对象软件开发所做的贡献,难以衡量。《重构:改善既有代码的设计》(中文版)解释重构的原理(principles)和最佳实践...
Martin Fowler的Inversion of Control Containers and the Dependency Injection pattern。中文版。 本文中,作者深入探索IOC模式的工作原理,给它一个更能描述其特点的名字——“依赖注入”(Dependency Injection...
### Martin Fowler 控制反转与依赖注入 #### 重要概念与背景 Martin Fowler的文章探讨了Java社区近期关注的一个热点话题:轻量级容器及其背后的模式。这些容器的主要目标是帮助开发者将来自不同项目的组件组装成一...
[作者信息] Martin Fowler [出版机构] Addison-Wesley Professional [出版日期] 1996年10月19日 [图书页数] 384页 [图书语言] 英语 [图书格式] PDF格式 ======================================================= ...
《设计已死——Martin Fowler》这篇文章探讨了软件开发中的设计理念,特别是对演进式设计的深入剖析。在软件工程领域,设计是构建高质量系统的关键环节,而Martin Fowler的观点引发了业界对于传统设计方法与演进式...
这一理念最早由Martin Fowler在其著作中提出,并逐渐成为软件开发流程中的核心环节。持续集成强调的是团队成员频繁地将自己的代码合并至主干,一般情况下每位开发者每天都需要执行一次或多于一次的集成操作。通过...
这本书第一章讲得实例在现实中经常碰到,至于后续章节需要慢慢品味,除非你只想做个平庸的程序员!
重构,一言以蔽之,就是在不改变外部行为的前提下,有条不紊地改善代码。多年前,正是本书原版的出版,使重构终于从编程高手们的小圈子走出,成为众多普通程序员日常开发工作中不可或缺的一部分。...