脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Ruby - ruby 迭代器使用方法

ruby 迭代器使用方法

2020-04-08 20:55脚本之家 Ruby

迭代器 并不是Ruby发明的.它广泛地运用于各种面向对象语言.在Lisp中也有,只是不这么叫罢了.尽管如此,迭代器的概念并不为许多人熟悉,因此我们将在此做较为详细的介绍. 你知道,动词iterate的意思是做同一件事许多遍,因此,iterator就

迭代器并不是Ruby发明的.它广泛地运用于各种面向对象语言.在Lisp中也有,只是不这么叫罢了.尽管如此,迭代器的概念并不为许多人熟悉,因此我们将在此做较为详细的介绍.

你知道,动词iterate的意思是做同一件事许多遍,因此,iterator就是用来将同一件事做许多次的东西.

当我们写代码时,我们需要各种环境下的循环.在C里,我们用for或者while.比如,

char*str;

for(str="abcdefg";*str!='\0';str++){

/*processacharacterhere*/

}

C的for(...)语法提供了一种写循环的抽象方法,但测试*str是否为空(null)字符需要程序员了解字符串内部结构的细节.这让C看起来像低级(low-level)语言.更高级的语言是通过它们更具弹性的迭代器支持来实现的.考虑下面的sh命令行脚本:

#!/bin/sh

foriin*.[ch];do

#...herewouldbesomethingtodoforeachfile

done

当前目录下所有的C源文件和头文件都将被处理,由命令行shell来一个个地捡取文件名并处理其中的细节.我想这是在比C要高的级别上工作,你觉得呢?

但有更多值得我们考虑的:在一种语言能够很好的给内建的数据类型的提供迭代器的同时,我们却仍需要回去用低级别的循环语言来实现对自己定义的数据类型的迭代,这真是让人失望.在面对对象编程时,用户经常一个接一个地定义数据类型,因此这是一个很严重的问题.

因此,所有的OOP语言都包含了一定的迭代器机制.某些语言为此提供一种特殊的类;Ruby则允许我们直接定义迭代器.

Ruby的String类型有很多有用的迭代器:

ruby>"abc".each_byte{|c|printf"<%c>",c};print"\n"

nil

each_byte是个用于字符串中每个字符的迭代器.每个字符串由局部变量c代替.这可以翻译为类似C的代码...

ruby>s="abc";i=0

0

ruby>whilei

|printf"<%c>",s[i];i+=1

|end;print"\n"

nil

...然而,each_byte迭代器在概念上要简单些,而且即使以后String类突然有所改变也应该可以照样工作.使用迭代器的一个好处便是在此类改变中仍然可以保持健壮;一般的,它的确是好代码的一个特点.(好,请有点儿耐心,我们将会马上谈到什么是类)

String的另一个迭代器是each_line.

ruby>"a\nb\nc\n".each_line{|l|printl}

a

c

nil

采用迭代器,这将很轻松的取代C的大多数编程效果(找换行符,生成子串等等)

前面出现的for语句通过each迭代器实现迭代功能.String的each和each_line的工作原理差不多,让我们用for重写上面的例子:

ruby>forlin"a\nb\nc\n"

|printl

|end

a

c

nil

我们可以用retry流程控制语句连接迭代循环,它会从头执行当前循环的迭代.

ruby>c=0

0

ruby>foriin0..4

|printi

|ifi==2andc==0

|c=1

|print"\n"

|retry

|end

|end;print"\n"

012

01234

nil

yield有时会在一个迭代器的定义中出现.yield将流程控制移至传递给迭代器的代码域(这将会在过程对象那一节介绍更多的细节).下面的例子定义了一个repeat迭代器,会依参数的设置执行多次代码域.

ruby>defrepeat(num)

|whilenum>0

|yield

|num-=1

|end

|end

nil

ruby>repeat(3){print"foo\n"}

foo

foo

foo

nil

利用retry,我们可以定义一个有while相同作用的迭代器,虽然在实际应用中它太慢了.

ruby>defWHILE(cond)

|returnifnotcond

|yield

|retry

|end

nil

ruby>i=0;WHILE(i<3){printi;i+=1}

012nil

搞懂什么是迭代器了吗?有一些限制,但你可以写自己的迭代器;实际上,当你定义一个新的数据类型时,为它定义一个合适的迭代器经常也很方便.这样看来,上面的例子并不是很好用.在我们理解了类以后,我们可以讨论讨论更具实际意义的迭代器.

延伸 · 阅读

精彩推荐
  • RubyRuby设计模式编程中使用Builder建造者模式的实例

    Ruby设计模式编程中使用Builder建造者模式的实例

    这篇文章主要介绍了Ruby设计模式编程中使用Builder建造者模式的实例,建造者模式将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表...

    范孝鹏2192020-05-07
  • RubyCentOS中配置Ruby on Rails环境

    CentOS中配置Ruby on Rails环境

    经过一个上午的折腾,终于把ROR环境在CentOS中搞定,绕了很多弯路,把文章写下来总结一下 ...

    可乐加糖4762020-04-12
  • Ruby简要说明Ruby中的迭代器

    简要说明Ruby中的迭代器

    这篇文章主要介绍了Ruby中的迭代器,迭代器的概念在动态语言的编程中十分重要,文章中介绍了Ruby中的each迭代器和collect迭代器,需要的朋友可以参考下 ...

    goldensun2772020-04-25
  • RubyRuby环境下安装使用bundler来管理多版本的gem

    Ruby环境下安装使用bundler来管理多版本的gem

    这篇文章主要介绍了Ruby环境下安装使用bundler来管理多版本的gem的方法,举了Ruby On Rails中的应用实例来进行演示,需要的朋友可以参考下 ...

    日拱一卒4332020-05-10
  • RubyRuby进行文件信息输出实例代码

    Ruby进行文件信息输出实例代码

    Ruby进行文件信息输出实例代码,数据是随机的,所以每次的记录都会不同。 ...

    ruby教程网2962020-04-10
  • Ruby剖析 Ruby 访问控制

    剖析 Ruby 访问控制

    前面,我们说 Ruby 没有函数,只有方法.而且实际上有不止一种方法.这一节我们介绍 访问控制 (accesscontrols). 想想当我们在最高层而不是在一个类的定义里定义...

    ruby教程网3572020-04-08
  • RubyRuby简洁学习笔记(一):字符串、数字、类和对象

    Ruby简洁学习笔记(一):字符串、数字、类和对象

    这篇文章主要介绍了Ruby简洁学习笔记(一):字符串、数字、类和对象,本文是学习笔记第一篇,需要的朋友可以参考下 ...

    脚本之家2472020-04-20
  • RubyRuby迭代器的7种技巧分享

    Ruby迭代器的7种技巧分享

    这篇文章主要介绍了Ruby迭代器的7种技巧分享,Ruby中的迭代器非常人性化,本文既是讲解了7个技巧也是讲解了7种迭代器,需要的朋友可以参考下 ...

    脚本之家4782020-04-20