知识讲解 Ruby迭代器
创始人
2024-06-15 22:50:27
0

首先,我们需要知道什么是Ruby语言。这是一款比较新的解释型脚本语言。完全面向对象。那么对于Ruby迭代器又有多少人清楚呢?#t#

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

你知道,动词 iterate 的意思是做同一件事许多遍,因此,iterator就是用来将同一件事做许多次的东西. 当我们写代码时,我们需要各种环境下的循环.在C里,我们用for或者while.比如,

  1. char *str;   
  2. for (str = "abcdefg"
    *str != '\0'; str++) {   
  3. /* process a character here */   
  4. }  

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

  1. #!/bin/sh   
  2. for i in *.[ch]; do   
  3. # ... here would be something 
    to do for each file   
  4. done  

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

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

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

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

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

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

  1. ruby> s="abc";i=0   
  2. 0   
  3. ruby> while i
  4. | printf "<%c>", s[i]; i+=1   
  5. | end; print "\n"   
  6.    
  7. nil  

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

  1. ruby> "a\nb\nc\n".each_
    line{|l| print l}   
  2. a   
  3. c   
  4. nil  

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

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

  1. ruby> for l in "a\nb\nc\n"   
  2. | print l   
  3. | end   
  4. a   
  5. c   
  6. nil  

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

  1. ruby> c=0   
  2. 0   
  3. ruby> for i in 0..4   
  4. | print i   
  5. | if i == 2 and c == 0   
  6. | c = 1   
  7. | print "\n"   
  8. | retry   
  9. | end   
  10. | end; print "\n"   
  11. 012   
  12. 01234   
  13. nil  

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

  1. ruby> def repeat(num)   
  2. | while num > 0   
  3. | yield   
  4. | num -= 1   
  5. | end   
  6. | end   
  7. nil   
  8. ruby> repeat(3) { print "foo\n" }   
  9. foo   
  10. foo   
  11. foo   
  12. nil  

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

  1. ruby> def WHILE(cond)   
  2. | return if not cond   
  3. | yield   
  4. | retry   
  5. | end   
  6. nil   
  7. ruby> i=0; WHILE(i<3) 
    { print i; i+=1 }   
  8. 012 nil  

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

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...