免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3631 | 回复: 5
打印 上一主题 下一主题

什么叫做closure? 哪位兄弟能够给出closure一个严谨的中文定义? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-30 18:40 |只看该作者 |倒序浏览
经常听到closure,哪位兄弟能够给出closure一个严谨的中文定义,最好再举个例子。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2008-07-30 19:24 |只看该作者
原帖由 perlish 于 2008-7-30 18:40 发表
经常听到closure,哪位兄弟能够给出closure一个严谨的中文定义,最好再举个例子。

看看 Wikipedia 的解释吧,http://en.wikipedia.org/wiki/Closure_%28computer_science%29

btw,若你有 Scheme 的经验,这个就更好理解了。

另外,closure 在 Perl 中的使用可以看看 Perl FAQ 7 的 What's a closure? (perldoc -q closure) 以及 perlref 中的介绍。

[ 本帖最后由 MMMIX 于 2008-7-30 19:27 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-07-30 19:29 |只看该作者
原帖由 MMMIX 于 2008-7-30 19:24 发表

看看 Wikipedia 的解释吧,http://en.wikipedia.org/wiki/Closure_%28computer_science%29

btw,若你有 Scheme 的经验,这个就更好理解了。

另外,closure 在 Perl 中的使用可以看看 Perl FAQ 7 的 Wha ...

能否用自己的理解尝试解释下。

论坛徽章:
0
4 [报告]
发表于 2008-07-31 13:21 |只看该作者
我在intermediate perl书上看来的,例子如下

use File::Find;

my $callback;
{
  my $count = 0;
  $callback = sub { print ++$count, ": $File::Find::name\n" };
}
find($callback, '.');

在{}之间的变量在代码块结束后理应全部失效,但是由于$callback是外部代码块的变量,而且这个函数使用了$count变量,所以{}构成了一个闭包,他们里面的变量都不会失效

论坛徽章:
0
5 [报告]
发表于 2011-10-12 12:11 |只看该作者
本帖最后由 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]). 然而在其它大部分语言中, 闭包的使用隐藏在语言的实现中, 不能直接被程序员使用. 如果仔细的做这些具有一定优势, 因此这种实现可以保证正确的使用闭包.

论坛徽章:
0
6 [报告]
发表于 2011-10-12 12:51 |只看该作者
抄自 Modern Perl
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP