第6章 循环

本章我们会讲述:

  • 程序中的循环是什么
  • 写循环时需要注意什么
  • 循环的种类及其写法

6.1 循环的基础

6.2循环的注意事项

  • 循环的主体是什么
  • 停止循环的条件是什么

6.3 实现循环的方法

Ruby中有两种实现循环的方法

  • 使用循环语句
    利用 Ruby 提供现有的循环语句,可以满足大部分循环处理的需求。
  • 使用方法实现循环
    将块传给方法,然后在块里面写上需要循环的处理。一般我们在为了某种特定目的而需要定制循环结构时,才使用方法来实现循环。 下面是我们接下来要介绍的六种循环语句或方法。
    • times方法
    • while语句
    • each方法
    • for语句
    • until语句
    • loop方法

6.4 times 方法

如果只是单纯执行一定次数的处理,用 times 方法可以很轻松实现。 假设我们希望把“满地油菜花”这个字符串连续输出 7 次。

7.times do
    puts "满地油菜花"
end

执行示例:

ruby times.rb 
满地油菜花 
满地油菜花 
满地油菜花 
满地油菜花 
满地油菜花 
满地油菜花 
满地油菜花

使用 times 方法实现循环时,需要用到块 do ~ end。

循环次数.times do
    希望循环的处理
end

块的do ~ end部分可以用 {~}代替,即

循环次数.times {
    希望循环的处理
}

6.5 for 语句

for 语句同样是用于实现循环的。需要注意的是,与刚才介绍的 times 方法不同,for 并不是方法,而是 Ruby 提供的循环控制语句。

代码清单 6.4 for.rb

sum = 0
for i in 1..5
    sum = sum + i
end
puts sum

执行示例:

ruby for.rb
15

for 语句的结构:

for 变量in开始时的数值..结束时的数值 do
    希望处理的循环
end

可以省略do

6.6 普通的for语句

for 变量 in 对象 do
    希望循环的处理
end

下面是使用数组对象的例子。

names = ["awk", "Perl", "Python", "Ruby"]
for name in names
    puts name
end

6.7 while 语句

不管哪种类型的循环,while 语句都可以胜任,while 语句的结构如下:

while 条件 do
    希望循环的处理
end

6.8 until语句

与 if 语句相对的有 unless 语句,同样地,与 while 语句相对的有 until 语句。until 语句的结构与 while 语句完全一样,只是条件判断刚好相反,不满 足条件时才执行循环处理。换句话说,while 语句是一直执行循环处理,直到条件不成立为止;until 语句是一直执行循环处理,直到条件成立为止。

until 条件 do
    希望循环的处理
end

虽然可以使用 while 语句的否定形式代替 until 语句。但是,有时对一些比较复杂的条件表达式使用否定,反而会不直观,影响程序理解,在这种情况下, 我们应该考虑使用 until 语句。

6.9 each 方法

each 方法将对象集合里的对象逐个取出,这与 for 语句循环取出数组元素非常相似。实际上,我们可以非常简单地将使用 for 语句的程序(代码清单 6.5) 改写为使用 each 方法的程序(代码清单 6.11)。

代码清单 6.11 each_names.rb

names = ["awk", "Perl", "Python", "Ruby"]
names.each do |name|
    puts name
end

each 方法的结构如下:

对象.each do |变量|
    希望循环的处理
end

块的 do ~ end 部分可换成 { ~ }。
这与下面的程序的效果是几乎一样。

for 变量 in 对象
    希望循环的处理
end

在 Ruby 内部,for 语句是用 each 方法来实现的。因此,可以使用 each 方法的对象,同样也可以指定为 for 语句的循环对象。 在介绍 for 语句时我们举过使用范围对象的例子(代码清单 6.4),我们试着用 each 方法改写一下。

代码清单 6.12 each.rb

sum = 0
(1..5).each do |i|
    sum = sum + i
end
puts sum

像本例这样,我们可以轻松互相改写两种用法。那到底什么时候该用 for 语句,什么时候该用 each 方法呢,我们将在本章的最后讨论这个问题。

6.10 loop 方法

还有一种循环的方法,没有终止循环条件,只是不断执行循环处理。Ruby 中的 loop 就是这样的循环方法。

loop do 
    print "Ruby"
end

执行上面的程序后,整个屏幕会不停的输出文字 Ruby。为了避免这样的情况发生,在实际使用 loop 方法时,我们需要用到接下来将要介绍的 break,使程 序可以中途跳出循环。

6.11 循环控制

break 终止程序,跳出循环
next 跳到下一次循环
redo 在相同的条件下重复刚才的处理

另外,大家要注意 redo 的使用方法,稍不留神就会在同样的条件下,不断地重复处理,陷入死循环中。 break、next 和 redo 中,一般比较常用是 break 和 next。大家应该熟练掌握这两个命令的用法。即使是 Ruby 默认提供的库里面,实际上也很难找到 redo 的踪影,所以当我们在希望使用 redo 时,应该好好考虑是否真的有必要使用 redo。

6.12 总结

如果纯粹只考虑实现循环功能,任何种类的循环都可以用 while 语句实现。讲得极端一点,其他循环语句和方法根本也没存在的必要。即便如此,那为什么 Ruby 还提供了那么丰富的循环语句和方法呢。这是因为,程序并不只是单纯为了实现功能,同时还应该使代码更便于读写,使人更容易理解。
下面我们简要介绍一下各种循环应在何时使用:
times 方法 确定循环次数时使用
for 语句 从对象去除元素时使用(each的语法糖)
while 语句 希望自由指定循环条件时使用
until 语句 使用while语句使循环变得难懂时使用
each 方法 从对象取出元素时使用
loop 方法 不限制循环次数时使用

PS:语法糖(syntax sugar),是指一种为了照顾一般人习惯而产生的特殊语法 1。例如,使用常规的语法调 用方法,那么加法运算应该写成 3.add(2)。 但是对于一般人来说,写成 3 + 2 会更直观,更简明易懂。 语法糖并不会加强编程语言的任何功能,但是对于提高程序的易读性来讲是不可或缺的。

确定循环次数时循环处理使用 times 方法,除此以外的大部分循环处理,根据情况选择 while 语句或者 each 方法,一般也能写出直观易懂的程序。请大家 先熟练掌握这三种循环方法。

do~end 与 {~}
在 times 方法的示例中,我们介绍了块的两种写法,do ~ end 与 { ~ }。从执行效果来看,两种方法虽然没有太大区别,但一般我们会遵守以下这 个约定俗成的编码规则:

  • 程序是跨行写的时候使用 do ~ end。
  • 程序写在 1 行的时候用 { ~ }。
    例如:
10.times do |i| 
     puts i 
end

or

10.times{|i| puts i

刚开始大家可能会有点不习惯。我们可以这样理解,do ~ end 表示程序要执行内容是多个处理的集合,而 { ~ } 则表示程序需要执行的处理只有一 个,即把整个带块的方法看作一个值。
如果用把 do ~ end 代码合并在一起,程序会变成下面这样:

10.times do |i| puts i end

以上写法,怎么看都给人一种很难断句的感觉。虽然实际上使用哪种写法都不会影响程序的运行,但在刚开始编写程序时,还是建议大家先遵守这个编 码规则。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容