- 论坛徽章:
- 0
|
本帖最后由 sudayly 于 2011-10-12 12:18 编辑
回复 1# perlish
这是来自Programming Paradigms for Dummies: What Every Programmers Should Know的一小段解释闭包概念,一些标记直接忽略掉就行了。
\subsection{Lexically scoped closure}
词法范围闭包是一种强有力的概念, 因而处于编程的核心地位. 函数式编程, 其使用闭包编程, 是一种中心范式(见图2). 从实现角度来看, 闭包把程式与其外部引用(其定义时所用引用)组合在一起. 从一个程序员的角度看, 闭包是``工作的封装'': 程序可以在其任一点时刻传输任何指令到闭包, 传送到另外的点决定在那点执行. 其执行的结果就好像闭包在那里创建而执行指令似的.
示意图9显示了创建和调用闭包所发生的. 过程P由闭包实现. 在定义(上下文D)的时候, P保存了定义上下文中的引用. 如, 其保持引用$x$到一些有名状态. 我们说, P的环境(引用集)在其定义的上下文是闭合的. 在调用的时候(C上下文), P使用上下文D的引用.
图10显示一个闭包的可能使用方式: 创建一个控制结构. 在左边, 我们执行指令<stmt>. 在右边, 作为执行<stmt>的替代, 我们把其放进一个过程(闭包), 由P引用(例子使用Oz语法). 在程序中任意时刻之后, 我们可以决定调用P. 我们分开了<stmt>的定义与执行. 有了这个能力之后, 我们可以定义控制结构, 如\texttt{if}语句或\texttt{while}循环.
图9和图10的例子可以很方便地泛化成带参数的过程. 闭合环境和前面一样存在. 每次调用都传递参数. 因此闭包有两类引用: 闭合环境(来自定义)和参数(来自每次调用). 几乎所有编程语言(除了少量值得尊敬的祖先, 如Pascal和C)使用这类闭包:
\begin{itemize}
\item 函数是闭包;
\item 过程是闭包;
\item 对象是闭包;
\item 类是闭包;
\item 软件组件是闭包.
\end{itemize}
平常与特定范式相关联的许多能力都基于闭包:
\begin{itemize}
\item 实例化和泛化, 平常与面向对象编程关联, 可以很容易地通过返回其它函数的函数来实现. 在面向对象编程中, 第一类函数称作``类'', 第二类称为``对象''.
\item 关系的分离, 平时与面向方面的编程想联系, 可以很容易地通过写以其它函数为参数的函数来实现. 如, Erlang有一个函数实现了通用容错client/server. 其调用函数参数, 该函数参数定义了服务器的行为. 使用面向对象语言进行基于方面的编程在本章中由Pierre Cointe[9]解释. 其通常使用语义转换(叫作``weaving''), 在原来代码中加入方面代码实现. AspectJ语言是这方面极好的例子. 使用weaving非常困难, 因为其脆弱: 其极易在程序中引入错误(改变源代码改变程序的语义). 使用闭包替换使得更容易地保持正确性, 因为源代码没有改变.
\item 基于组件的编程是一种编程风格, 程序以组件的方式组织, 每个组件可能依赖其它组件. 一个组件是一个详细说明部分程序的构建块. 一个组件的实例叫做模块, 一个包含闭包的记录. 新模块通过以其依赖的模块作为输入的函数创建. 组件就是这个函数.
\end{itemize}
Erlang语言直接使用闭包实现了所有这些能力. 这是切合实际的而且可放大的: 具有多于100万行Erlang源代码的成功商业产品被开发(如, AXD-301 ATM切换机[57]). 然而在其它大部分语言中, 闭包的使用隐藏在语言的实现中, 不能直接被程序员使用. 如果仔细的做这些具有一定优势, 因此这种实现可以保证正确的使用闭包.
|
|