第6章 循環(huán)

本章我們會(huì)講述:

  • 程序中的循環(huán)是什么
  • 寫(xiě)循環(huán)時(shí)需要注意什么
  • 循環(huán)的種類(lèi)及其寫(xiě)法

6.1 循環(huán)的基礎(chǔ)

6.2循環(huán)的注意事項(xiàng)

  • 循環(huán)的主體是什么
  • 停止循環(huán)的條件是什么

6.3 實(shí)現(xiàn)循環(huán)的方法

Ruby中有兩種實(shí)現(xiàn)循環(huán)的方法

  • 使用循環(huán)語(yǔ)句
    利用 Ruby 提供現(xiàn)有的循環(huán)語(yǔ)句,可以滿(mǎn)足大部分循環(huán)處理的需求。
  • 使用方法實(shí)現(xiàn)循環(huán)
    將塊傳給方法,然后在塊里面寫(xiě)上需要循環(huán)的處理。一般我們?cè)跒榱四撤N特定目的而需要定制循環(huán)結(jié)構(gòu)時(shí),才使用方法來(lái)實(shí)現(xiàn)循環(huán)。 下面是我們接下來(lái)要介紹的六種循環(huán)語(yǔ)句或方法。
    • times方法
    • while語(yǔ)句
    • each方法
    • for語(yǔ)句
    • until語(yǔ)句
    • loop方法

6.4 times 方法

如果只是單純執(zhí)行一定次數(shù)的處理,用 times 方法可以很輕松實(shí)現(xiàn)。 假設(shè)我們希望把“滿(mǎn)地油菜花”這個(gè)字符串連續(xù)輸出 7 次。

7.times do
    puts "滿(mǎn)地油菜花"
end

執(zhí)行示例:

ruby times.rb 
滿(mǎn)地油菜花 
滿(mǎn)地油菜花 
滿(mǎn)地油菜花 
滿(mǎn)地油菜花 
滿(mǎn)地油菜花 
滿(mǎn)地油菜花 
滿(mǎn)地油菜花

使用 times 方法實(shí)現(xiàn)循環(huán)時(shí),需要用到塊 do ~ end。

循環(huán)次數(shù).times do
    希望循環(huán)的處理
end

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

循環(huán)次數(shù).times {
    希望循環(huán)的處理
}

6.5 for 語(yǔ)句

for 語(yǔ)句同樣是用于實(shí)現(xiàn)循環(huán)的。需要注意的是,與剛才介紹的 times 方法不同,for 并不是方法,而是 Ruby 提供的循環(huán)控制語(yǔ)句。

代碼清單 6.4 for.rb

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

執(zhí)行示例:

ruby for.rb
15

for 語(yǔ)句的結(jié)構(gòu):

for 變量in開(kāi)始時(shí)的數(shù)值..結(jié)束時(shí)的數(shù)值 do
    希望處理的循環(huán)
end

可以省略do

6.6 普通的for語(yǔ)句

for 變量 in 對(duì)象 do
    希望循環(huán)的處理
end

下面是使用數(shù)組對(duì)象的例子。

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

6.7 while 語(yǔ)句

不管哪種類(lèi)型的循環(huán),while 語(yǔ)句都可以勝任,while 語(yǔ)句的結(jié)構(gòu)如下:

while 條件 do
    希望循環(huán)的處理
end

6.8 until語(yǔ)句

與 if 語(yǔ)句相對(duì)的有 unless 語(yǔ)句,同樣地,與 while 語(yǔ)句相對(duì)的有 until 語(yǔ)句。until 語(yǔ)句的結(jié)構(gòu)與 while 語(yǔ)句完全一樣,只是條件判斷剛好相反,不滿(mǎn) 足條件時(shí)才執(zhí)行循環(huán)處理。換句話(huà)說(shuō),while 語(yǔ)句是一直執(zhí)行循環(huán)處理,直到條件不成立為止;until 語(yǔ)句是一直執(zhí)行循環(huán)處理,直到條件成立為止。

until 條件 do
    希望循環(huán)的處理
end

雖然可以使用 while 語(yǔ)句的否定形式代替 until 語(yǔ)句。但是,有時(shí)對(duì)一些比較復(fù)雜的條件表達(dá)式使用否定,反而會(huì)不直觀,影響程序理解,在這種情況下, 我們應(yīng)該考慮使用 until 語(yǔ)句。

6.9 each 方法

each 方法將對(duì)象集合里的對(duì)象逐個(gè)取出,這與 for 語(yǔ)句循環(huán)取出數(shù)組元素非常相似。實(shí)際上,我們可以非常簡(jiǎn)單地將使用 for 語(yǔ)句的程序(代碼清單 6.5) 改寫(xiě)為使用 each 方法的程序(代碼清單 6.11)。

代碼清單 6.11 each_names.rb

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

each 方法的結(jié)構(gòu)如下:

對(duì)象.each do |變量|
    希望循環(huán)的處理
end

塊的 do ~ end 部分可換成 { ~ }。
這與下面的程序的效果是幾乎一樣。

for 變量 in 對(duì)象
    希望循環(huán)的處理
end

在 Ruby 內(nèi)部,for 語(yǔ)句是用 each 方法來(lái)實(shí)現(xiàn)的。因此,可以使用 each 方法的對(duì)象,同樣也可以指定為 for 語(yǔ)句的循環(huán)對(duì)象。 在介紹 for 語(yǔ)句時(shí)我們舉過(guò)使用范圍對(duì)象的例子(代碼清單 6.4),我們?cè)囍?each 方法改寫(xiě)一下。

代碼清單 6.12 each.rb

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

像本例這樣,我們可以輕松互相改寫(xiě)兩種用法。那到底什么時(shí)候該用 for 語(yǔ)句,什么時(shí)候該用 each 方法呢,我們將在本章的最后討論這個(gè)問(wèn)題。

6.10 loop 方法

還有一種循環(huán)的方法,沒(méi)有終止循環(huán)條件,只是不斷執(zhí)行循環(huán)處理。Ruby 中的 loop 就是這樣的循環(huán)方法。

loop do 
    print "Ruby"
end

執(zhí)行上面的程序后,整個(gè)屏幕會(huì)不停的輸出文字 Ruby。為了避免這樣的情況發(fā)生,在實(shí)際使用 loop 方法時(shí),我們需要用到接下來(lái)將要介紹的 break,使程 序可以中途跳出循環(huán)。

6.11 循環(huán)控制

break 終止程序,跳出循環(huán)
next 跳到下一次循環(huán)
redo 在相同的條件下重復(fù)剛才的處理

另外,大家要注意 redo 的使用方法,稍不留神就會(huì)在同樣的條件下,不斷地重復(fù)處理,陷入死循環(huán)中。 break、next 和 redo 中,一般比較常用是 break 和 next。大家應(yīng)該熟練掌握這兩個(gè)命令的用法。即使是 Ruby 默認(rèn)提供的庫(kù)里面,實(shí)際上也很難找到 redo 的蹤影,所以當(dāng)我們?cè)谙M褂?redo 時(shí),應(yīng)該好好考慮是否真的有必要使用 redo。

6.12 總結(jié)

如果純粹只考慮實(shí)現(xiàn)循環(huán)功能,任何種類(lèi)的循環(huán)都可以用 while 語(yǔ)句實(shí)現(xiàn)。講得極端一點(diǎn),其他循環(huán)語(yǔ)句和方法根本也沒(méi)存在的必要。即便如此,那為什么 Ruby 還提供了那么豐富的循環(huán)語(yǔ)句和方法呢。這是因?yàn)椋绦虿⒉恢皇菃渭優(yōu)榱藢?shí)現(xiàn)功能,同時(shí)還應(yīng)該使代碼更便于讀寫(xiě),使人更容易理解。
下面我們簡(jiǎn)要介紹一下各種循環(huán)應(yīng)在何時(shí)使用:
times 方法 確定循環(huán)次數(shù)時(shí)使用
for 語(yǔ)句 從對(duì)象去除元素時(shí)使用(each的語(yǔ)法糖)
while 語(yǔ)句 希望自由指定循環(huán)條件時(shí)使用
until 語(yǔ)句 使用while語(yǔ)句使循環(huán)變得難懂時(shí)使用
each 方法 從對(duì)象取出元素時(shí)使用
loop 方法 不限制循環(huán)次數(shù)時(shí)使用

PS:語(yǔ)法糖(syntax sugar),是指一種為了照顧一般人習(xí)慣而產(chǎn)生的特殊語(yǔ)法 1。例如,使用常規(guī)的語(yǔ)法調(diào) 用方法,那么加法運(yùn)算應(yīng)該寫(xiě)成 3.add(2)。 但是對(duì)于一般人來(lái)說(shuō),寫(xiě)成 3 + 2 會(huì)更直觀,更簡(jiǎn)明易懂。 語(yǔ)法糖并不會(huì)加強(qiáng)編程語(yǔ)言的任何功能,但是對(duì)于提高程序的易讀性來(lái)講是不可或缺的。

確定循環(huán)次數(shù)時(shí)循環(huán)處理使用 times 方法,除此以外的大部分循環(huán)處理,根據(jù)情況選擇 while 語(yǔ)句或者 each 方法,一般也能寫(xiě)出直觀易懂的程序。請(qǐng)大家 先熟練掌握這三種循環(huán)方法。

do~end 與 {~}
在 times 方法的示例中,我們介紹了塊的兩種寫(xiě)法,do ~ end 與 { ~ }。從執(zhí)行效果來(lái)看,兩種方法雖然沒(méi)有太大區(qū)別,但一般我們會(huì)遵守以下這 個(gè)約定俗成的編碼規(guī)則:

  • 程序是跨行寫(xiě)的時(shí)候使用 do ~ end。
  • 程序?qū)懺?1 行的時(shí)候用 { ~ }。
    例如:
10.times do |i| 
     puts i 
end

or

10.times{|i| puts i

剛開(kāi)始大家可能會(huì)有點(diǎn)不習(xí)慣。我們可以這樣理解,do ~ end 表示程序要執(zhí)行內(nèi)容是多個(gè)處理的集合,而 { ~ } 則表示程序需要執(zhí)行的處理只有一 個(gè),即把整個(gè)帶塊的方法看作一個(gè)值。
如果用把 do ~ end 代碼合并在一起,程序會(huì)變成下面這樣:

10.times do |i| puts i end

以上寫(xiě)法,怎么看都給人一種很難斷句的感覺(jué)。雖然實(shí)際上使用哪種寫(xiě)法都不會(huì)影響程序的運(yùn)行,但在剛開(kāi)始編寫(xiě)程序時(shí),還是建議大家先遵守這個(gè)編 碼規(guī)則。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容