ruby 迭代器使用方法
所属分类:
脚本专栏 / ruby专题
阅读数:
608
收藏 0赞 0分享
迭代器并不是Ruby发明的.它广泛地运用于各种面向对象语言.在Lisp中也有,只是不这么叫罢了.尽管如此,迭代器的概念并不为许多人熟悉,因此我们将在此做较为详细的介绍.
你知道,动词 iterate 的意思是做同一件事许多遍,因此,iterator就是用来将同一件事做许多次的东西.
当我们写代码时,我们需要各种环境下的循环.在C里,我们用for或者while.比如,
char *str;
for (str = "abcdefg"; *str != '\0'; str++) {
/* process a character here */
}
C的for(...)语法提供了一种写循环的抽象方法,但测试 *str 是否为空(null)字符需要程序员了解字符串内部结构的细节.这让C看起来像低级(low-level)语言.更高级的语言是通过它们更具弹性的迭代器支持来实现的.考虑下面的 sh 命令行脚本:
#!/bin/sh
for i in *.[ch]; do
# ... here would be something to do for each file
done
当前目录下所有的C源文件和头文件都将被处理,由命令行shell来一个个地捡取文件名并处理其中的细节.我想这是在比 C 要高的级别上工作,你觉得呢?
但有更多值得我们考虑的:在一种语言能够很好的给内建的数据类型的提供迭代器的同时,我们却仍需要回去用低级别的循环语言来实现对自己定义的数据类型的迭代,这真是让人失望.在面对对象编程时,用户经常一个接一个地定义数据类型,因此这是一个很严重的问题.
因此,所有的OOP语言都包含了一定的迭代器机制.某些语言为此提供一种特殊的类;Ruby则允许我们直接定义迭代器.
Ruby的String类型有很多有用的迭代器:
ruby> "abc".each_byte{|c| printf "<%c>", c}; print "\n"
<a><b><c>
nil
each_byte 是个用于字符串中每个字符的迭代器.每个字符串由局部变量c代替.这可以翻译为类似C的代码...
ruby> s="abc";i=0
0
ruby> while i<s.length
| printf "<%c>", s[i]; i+=1
| end; print "\n"
<a><b><c>
nil
...然而, each_byte 迭代器在概念上要简单些,而且即使以后 String 类突然有所改变也应该可以照样工作.使用迭代器的一个好处便是在此类改变中仍然可以保持健壮;一般的,它的确是好代码的一个特点.(好,请有点儿耐心,我们将会马上谈到什么是类)
String的另一个迭代器是 each_line.
ruby> "a\nb\nc\n".each_line{|l| print l}
a
c
nil
采用迭代器,这将很轻松的取代C的大多数编程效果(找换行符,生成子串等等)
前面出现的for语句通过each迭代器实现迭代功能. String的each和each_line的工作原理差不多,让我们用for重写上面的例子:
ruby> for l in "a\nb\nc\n"
| print l
| end
a
c
nil
我们可以用retry流程控制语句连接迭代循环,它会从头执行当前循环的迭代.
ruby> c=0
0
ruby> for i in 0..4
| print i
| if i == 2 and c == 0
| c = 1
| print "\n"
| retry
| end
| end; print "\n"
012
01234
nil
yield有时会在一个迭代器的定义中出现. yield将流程控制移至传递给迭代器的代码域(这将会在过程对象那一节介绍更多的细节).下面的例子定义了一个repeat迭代器,会依参数的设置执行多次代码域.
ruby> def repeat(num)
| while num > 0
| yield
| num -= 1
| end
| end
nil
ruby> repeat(3) { print "foo\n" }
foo
foo
foo
nil
利用retry,我们可以定义一个有while相同作用的迭代器,虽然在实际应用中它太慢了.
ruby> def WHILE(cond)
| return if not cond
| yield
| retry
| end
nil
ruby> i=0; WHILE(i<3) { print i; i+=1 }
012 nil
搞懂什么是迭代器了吗?有一些限制,但你可以写自己的迭代器;实际上,当你定义一个新的数据类型时,为它定义一个合适的迭代器经常也很方便.这样看来,上面的例子并不是很好用.在我们理解了类以后,我们可以讨论讨论更具实际意义的迭代器.
Ruby中常用的字符串处理函数使用实例
这篇文章主要介绍了Ruby中常用的字符串处理函数使用实例,本文总结了Ruby中最常用的字符串处理函数,如返回字符串的长度、判断字符串中是否包含另一个串、字符串插入、字符串分隔、默认分隔符为空格等内容,需要的朋友可以参考下
收藏 0赞 0分享
Windows下ruby语言安装教程
这篇文章主要介绍了Windows下ruby语言安装教程,本文使用rubyinstaller提供的安装包安装,并给出图文说明,非常简单,需要的朋友可以参考下
收藏 0赞 0分享
ruby环境中自动编译sass教程
这篇文章主要介绍了ruby环境中自动编译sass教程,本文讲解了ruby环境的安装、sass环境的安装以及sass的常用编译命令使用示例,需要的朋友可以参考下
收藏 0赞 0分享
Ruby中相等性判断的4种方法
这篇文章主要介绍了Ruby中相等性判断的4种方法,本文讲解了“==” 最常见的相等性判断、“===” 用于 case 语句的相容判断、“equal?” 相同对象判断、“eql?” 对象 hash 值判断等内容,需要的朋友可以参考下
收藏 0赞 0分享
Ruby中的p和puts的使用区别浅析
这篇文章主要介绍了Ruby中的p和puts的使用区别浅析,本文用一个实例讲解了它们之间的区别,并总结出结论,需要的朋友可以参考下
收藏 0赞 0分享
Ruby中的block、proc、lambda区别总结
这篇文章主要介绍了Ruby中的block、proc、lambda区别总结,本文讲解了yield 和 block call 的区别、block 和 proc、lambda 的区别、proc 和 lambda 的区别,需要的朋友可以参考下
收藏 0赞 0分享
Ruby的运算符和语句优先级介绍
这篇文章主要介绍了Ruby的运算符和语句优先级介绍,本文先是给出了一些小例子来验证运算符和语句优先级,然后总结出一个优先级表,需要的朋友可以参考下
收藏 0赞 0分享
查看更多