流程控制 <> 只要有風和海,我就有辦法航行!

[Day06] 風雷雨晴,海上的天氣由我決定!

來到了第 6 天,今天要跟大家介紹的是娜美的天氣棒 (咳咳咳) 我說的是 流程控制(Flow Controller)

只要進入程式語言的世界,就一定會經常碰到流程控制,在 Ruby 裡我們使用 if 判斷式來讓電腦知道,在哪些條件滿足時,要採取什麼樣的行為。


一開始,先分享一則有趣的小故事給大家:

事情是這樣的,某天有一位先生下班正要回家,太太打電話給他說:「回家的路上幫忙買 1 斤包子回來,如果有看到西瓜的話,就買 1 個。」說完就掛掉了電話,結果先生回到家後,太太發現他居然只買了 1 個包子,大為光火,一番詢問後…

先生委屈地表示,因為他在路上有看到西瓜…(繼續挨揍中)

上面這個小故事,可以看出這位先生正是巧妙地運用了流程控制的思考方式:

1
2
3
4
5
6
7
西瓜 = 1

if 西瓜 = 1
buy 1 個 包子
else
buy 1 斤 包子
end

不過如果照著上面這樣寫,實際上是會出錯的,因為在 if 後面應該要是一個進行比較的條件:

1
2
3
4
5
6
7
西瓜 = 1

if 西瓜 == 1 # 新手常常會寫錯的地方
buy 1 個 包子
else
buy 1 斤 包子
end

儘管程式寫對了,回家後這位先生可能還是會被太太念怎麼只買一顆包子吧…(請多保重)


只有這樣不然就那樣

對於愛恨分明的 if.. else.. 判斷式來說,就是非黑即白的二分法:

以經典的《霹靂火》舉例:

1
2
3
4
5
6
7
心情 = 金每送

if 心情 == 不爽
puts "給你一支番仔火,跟一桶汽油"
else
puts "代誌過去安捏丟厚"
end

事情解決的方式就只有兩種結局…要怎麼選,就要看對方的心情了


如果這樣就這樣,但那樣的話就那樣,還有…到底是怎樣?!

if 的判斷式不只有兩種時,結果就會變得很派(?),這時候就無法用簡單的二分法處理了,而是要使用 elsif 來增加判斷的條件,譬如:

1
2
3
4
5
6
7
8
9
10
11
age = 10

if age > 0 && age <= 3
puts "Baby"
elsif age > 3 && age <= 10
puts "Kids"
elsif age > 10 && age <= 17
puts "Teenager"
else
puts "Adult"
end

小提醒:在設定一個以上的條件時,不是用 else ifelseif ,而是 elsif ,中間有省略一個 e 喔!撰寫時請多加留意!


把 if 放到後面

如果 if 判斷式的條件很少,只夠寫一行程式碼:

1
2
3
if age >= 18
puts "adult"
end

這時候我們就可以把 if 判斷式接到後面去,變得很像英文的倒裝句:

1
puts "adult" if age >= 18

也可以用 Case/When 來寫看看

如果真的有太多的條件要判斷時,除了使用 if.. elsif.. 以外,還可以用 case.. when.. 這種 Ruby 語法糖衣,它的使用情境與 if 判斷式並沒有不同。

只是當存在太多條件時,就可以考慮把 if .. elsif.. 改寫成 case.. when.. 的形式,讓程式碼更好閱讀。

譬如:

1
2
3
4
5
6
7
8
9
10
11
12
懸賞 = 3 億貝里

case 懸賞
when 0..1 億貝里
puts "海賊新人"
when 2..3 億貝里
puts "超新星"
when >= 4 億貝里
puts "七武海"
else
puts "雜魚一枚"
end

這裡的 .. 是 Ruby 裡特有的範圍(Range)用法,只要在 .. 兩側放上首尾的字元,就可以用來表示一段區間的數字或字串了。


三元運算子

三元運算子(ternary operator)是一種由 ?: 區隔兩種條件的表達方式,雖然名字叫運算子,但它實際上更接近流程控制的條件判斷,譬如:

1
2
3
4
5
6
x = 3
if x > 3
y = "foo"
else
y = "bar"
end

如果以三元運算子來改寫會更精簡:

1
2
x = 3
y = ( x > 3 ) ? "foo" : "bar"

不過,撰寫程式時建議要優先考量可讀性,不要覺得三元運算子很酷,或是能少掉很多行程式碼就立馬使用三元運算子,結果過幾天完全看不懂自己在寫什麼,慎之!慎之!


今天就先到這邊啦!相信大家都已經學會使用流程控制了,以後上街買東西就可以輕鬆派上用場啦!(逃)