分享
 
 
 

[eiffel 翻译 artima.com 访谈录]Ruby 语言中 blocks 和 Closure 结构

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

注: Matz 就是著名的编程语言 Ruby 的创始人(日本人)

这段对话翻译自 artima.com 网站对 Matz 的访谈的第三部分。

英文文章原址: http://www.artima.com/intv/closures.html

未经本人同意,不要任何地方转载这篇翻译文章

(最先发表在本人的网站 http://www.eiffelqiu.com)。

使用 Blocks 做循环抽象

Bill Venners:

Ruby 支持 blocks 和 Closure 结构. 什么是 blocks 和 Closure, 他们如何使用?

Yukihiro Matsumoto:

Blocks 基本上就是匿名函数。你可能熟悉诸如Lisp 或 Python等其他语言中

的 Lambda 函数。 你可以向另外一个函数传递一个匿名函数,这个函数可以

调用这个被传递过来的匿名函数。例如, 函数可以通过一次传递给匿名函数一

个元素来执行循环迭代。在那些可以将函数当作第一类型的编程语言中,这是个

通常的方式,称为高排序函数样式。 Lisp 可以这样,Python 也是如此,甚至

就连C 也可以通过函数指针实现这点。很多其他语言也可以做这样的编程。

在 Ruby 中,不同之处只是在高排序函数语法风格上有所不同。在其他语言中,你

必须显示的指出一个函数可以接受另外一个函数作为参数。但是在Ruby 中,任何

方法都可以 Block 作为一个隐性参数被调用。在方法中,你可以使用 yield 关键字

和一个值来调用 block.

Bill Venners:

Block 的好处是什么?

Yukihiro Matsumoto:

基本上,Block 是被设计来做循环迭代抽象的。Block 最基本的使用就是让你

以自己的方式定义如何循环迭代。

例如,如果你有一个列表,序列,矢量组或者数组,你可以通过使用标准库中

提供的方法来实现向前循环迭代,但是如果你想从后往前实现循环迭代呢?如

果使用 C 语言,你得先设置四件事情:一个索引,一个起始值,一个结束条件

和一个递增变量。这种方式不好,因为它暴露了列表的内部实现方法,我们希

望能够隐藏内部逻辑,通过使用 Block 我们可以将内部循环迭代的方式隐藏在

一个方法或者函数中。比如,调用 list.reverse_each,你可以对一个列表实

现一个反向的循环迭代,而不需要知道列表内部是如何实现的。

Bill Venners:

就是说,我传递一个 Block 结构,这个 Block 中的代码可对循环迭代中每个

元素做任何事情,至于如何反向遍历就取决于List 本身了。换句话说,我就

是把原本在 C 语言 Loop 循环中写的那些代码作为一个 Block 来传递。

Yukihiro Matsumoto:

对,这意味着你可以定义许多迭代的方式。你可以提供一种向前循环迭代的方

式,一种向后循环迭代的方式,等等。这全取决于你了。C#也有迭代器,但是

它对于每个类只有一个迭代器。在 Ruby 中你可以拥有任意数量的迭代器。例

如,如果你有一个 Tree 类,可以让人以深度优先或者广度优先的方式遍历,

你可以通过提供两种不同的方法来提供两种遍历方式。

Bill Venners:

让我想想是否我了解了这点,在 Java 中,它们是通过 Iterator 接口实现抽

象迭代的,例如,调用程序可以让 Collection 来实现 Iterator。但是调用程

序必须使用循环来遍历Iterator 返回的元素。在 For 循环中, 我的代码实

现对每个循环迭代的元素的处理,这样循环语句将总是显示在调用程序中。 使

用 Block , 我并不调用一个方法来获取一个迭代器,我只是调用一个方法,同

时将我希望对循环迭代中每个要处理的元素的处理代码作为一个 Block 块结

构传递给该函数。 Block 的好处是不是将一些代码从调用程序中的 for 循环

中提取出来。

Yukihiro Matsumoto:

实现循环迭代的具体细节应该属于提供这个功能的类。调用程序应该尽可能的少

知道这些。这就是 Block 结构的本来目的。实际上,在早期版本的 Ruby 中,

使用 Block 的方法被称为迭代器,因为它们就是被设计来实现循环迭代的。但

是在 Ruby发展过程中,Block 的用途在后来已经得到了很大的增强,从最初的循环

抽象到任何事情。

Bill Venners:

例如。。。。

Yukihiro Matsumoto:

我们可以从Block 中创建一个 Closure 对象,一个 Closure 对象就是像 Lisp

中实现的那种匿名函数。 你可以向任何方法传递一个匿名函数(即 Closure)来

自定义方法的行为。另外举个例子,如果你有一个排序的方法用于排序数组或者

列表,你可以定义一个 Block 来定义如何在元素之间进行比较,这不是循环迭代。

这不是个循环,但是它使用了 Block 。

Bill Venners:

什么使得 Block 成为了一个 Closure?

Yukihiro Matsumoto:

Closure 对象包含可以运行的代码,是可执行的,代码包含状态,执行范围。

也就是说在Closure 中你捕捉到运行环境,即局部变量。因此,你可以在一个

Closure 中引用局部变量,即是在函数已经返回之后,他的执行范围已经销毁掉,

局部变量依然作为一部分存在于Closure 对象中,当没有任何对象引用它的时候,

垃圾搜集器将处理它,局部变量将消失。

Bill Venners:

这么说,局部变量基本上是被方法和Closure 对象共享的?如果 Closure 对象

更新了变量,方法可以看到,如果方法更新了变量,Cosure 对象也可以看到。

Yukihiro Matsumoto:

是的,局部变量在Closure 和方法之间共享,这是真正的 Closure,它不仅仅是

复制。

Bill Venners:

一个真正的 Closure 有什么好处?一旦我将一个 Block 变为一个 Closure,我

能用它做什么?

Yukihiro Matsumoto:

你可以将一个 Closure 转换为一个 Block,所以 Closure 可以被用在任何 Block

可以使用的地方。通常, Closure 用来将一个 Block 的状态保存在一个实例变量中,

因为一旦你将一个 Block 转换为一个 Closure, 它就是一个通过变量可以引用的对

象了。当然Closure 也可以像其他语言中那样使用 ,例如传递给对象以实现对方法

行为的定义。如果你希望传递一些代码来自定义一个方法, 你当然可以传递给它一个

Block. 但是如果你想将同样的代码传递给两个方法(当然这是非常少见的情况),但

是如果你确实想这么做,你可以将一个 Block 转换为一个 Closure ,将同一个 Closure

传递给多个方法。

Bill Venners:

原来如此,但是获取上下文环境有什么好处呢?真正让 Ruby 的 Closure 不同的是

它捕捉运行时间的上下文环境,局部变量等等。那么到底拥有上下文环境有什么好

处是我们无法通过传递给对象一个代码块所获得的呢?

Yukihiro Matsumoto:

实际上,说实在的,最主要的原因是向 Lisp 语言表达敬意, Lisp 提供了真正的

Closure 结构,所以我希望继续提供这个功能。

Bill Venners:

我看到的一个不同之处是: 数据在Closure 对象和方法之间共享。我想我可以在

一个常规的非 Closure 结构的 Block 中放入任何需要的环境数据作为参数来传

递,但是 Block 仅仅是对环境数据的一份复制,并不是真正的 Closure. 它并没有

共享环境数据。共享是Closure 和普通的传统函数对象不同的地方。

Yukihiro Matsumoto:

是的,共享允许你做一些有趣的代码演示,但是我觉得它对于程序员的日常工作并

没有想象的那么有用。这没什么太大的关系,例如像 Java 的内部类那样的普通复

制,在许多场合都在使用。但是通过 Ruby 的Clousure 结构,我希望表达我对Lisp 文化的致意。

邱海峰(eiffelqiu)

mail: eiffel_q@163.com

www: http://www.eiffelqiu.com

weblog: http://mulder.5d.cn

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有