這章我們將討論更多的Ruby流程控制.
case
我們用case語句測試有次序的條件.正如我們所見的,這和C,Java的switch相當接近,但更強大.
ruby>?i=8
ruby>?case?i
????|?when?1,?2..5
????|???print?"1..5/n"
????|?when?6..10
????|???print?"6..10/n"
????|?end
6..10
???nil?
2..5表示2到5之間的一個范圍.下面的表達式測試?i?是否在范圍內:
(2..5)?===?i?
case?內部也是用關系運算符?===?來同時測試幾個條件.為了保持ruby的面對對象性質,?===?可以合適地理解為出現在?when?條件里的對
象.比如,下面的代碼現在第一個?when?里測試字符串是否相等,并在第二個?when?里進行正則表達式匹配.
ruby>?case?'abcdef'
????|?when?'aaa',?'bbb'
????|???print?"aaa?or?bbb/n"
????|?when?/def/
????|???print?"includes?/def//n"
????|?end
includes?/def/
???nil?
while
雖然你將會在下一章發現并不需要經常將循環體寫得很清楚,但?Ruby?還是提供了一套構建循環的好用的方法.
while?是重復的?if.我們在猜詞游戲和正則表達式中使用過它(見前面的章節);這里,當條件(condition)為真的時候,它圍繞一個代碼域以
while?condition...end的形式循環.但?while?和?if?可以很容易就運用于單獨語句:
ruby>?i?=?0
???0
ruby>?print?"It's?zero./n"?if?i==0
It's?zero.
???nil
ruby>?print?"It's?negative./n"?if?i???nil
ruby>?print?"#{i+=1}/n"?while?i1
2
3
???nil?
有時候你想要否定一個測試條件.?unless?是?if?的否定,?until?是一個否定的?while.在這里我把它們留給你實驗.
There?are?four?ways?to?interrupt?the?progress?of?a?loop?from?inside.?First,?break?means,?as?in?C,?to?escape?from?the?
loop?entirely.?Second,?next?skips?to?the?beginning?of?the?next?iteration?of?the?loop?(corresponding?to?C's?continue).?
Third,?ruby?has?redo,?which?restarts?the?current?iteration.?The?following?is?C?code?illustrating?the?meanings?of?break,?
next,?and?redo:
有四種從內部中斷循環的方法.第一,和C一樣break從循環中完全退出.第二,?next?跳到下一次循環迭代的開始(對應于C的?continue?).第
三,Ruby有redo,它可以重新開始現在的迭代.下面是用?C?代碼對break,next,redo的意義做了演示:
while?(condition)?{?
???label_redo:???
??????goto?label_next;????????/*?ruby's?"next"?*/???
??????goto?label_break;???????/*?ruby's?"break"?*/???
??????goto?label_redo;????????/*?ruby's?"redo"?*/???
??????...???
??????...?
??????label_next:
}
label_break:
...?
第四種方法是由循環內跳出的方法是?returen.?return的結果是不僅從循環中跳出,而且會從含循環的方法中跳出.如果有參數,它會返回給方法調用,不然就返回nil.
for
C程序員現在會想知道怎樣做一個"for"循環.Ruby的for比你想象的要有趣一點.下面的loop由集合中的元素控制運行:
for?elt?in?collection??
?????...
end?
集合可以是一個數集(也是傳統意義上的for循環):
ruby>?for?num?in?(4..6)
????|????print?num,"/n"
????|?end
4
5
6
???4..6?
也可以是其它的什么類型的集合,比如一個數組:
ruby>?for?elt?in?[100,-9.6,"pickle"]
????|????print?"#{elt}/t(#{elt.type})/n"
????|?end
100????(Fixnum)
-9.6???(Float)
pickle?(String)
???[100,?-9.6,?"pickle"]?
但我們說過頭了.for其實是?each?的另一寫法,正巧,這是我們關于迭代器的第一個例子.下面的兩種形式是等價的:
#??If?you're?used?to?C?or?Java,?you?might?prefer?this.
for?i?in?collection??
???...
end
#??A?Smalltalk?programmer?might?prefer?this.
collection.each?{|i|
???...
}?
一旦你熟悉了迭代器,它便會常常代替傳統的循環.它們一般更容易處理.因此,讓我們接著學習更多關于迭代器的知識.