你知道除了使用 If
來進行條件判斷外,還可以使用 Guard
嗎?
在條件判斷除了 If
和 Switch
,還有一種判斷方式跟 If
很像,那就是 Guard
。
先來看一下 Guard 的使用方式:
guard 條件 else {
...
}
Guard
一樣是透過 Boolean 來判斷條件,但是跟 If
不太一樣的地方是,Gurad
結尾都必須加上 else
,如果條件不成立就會執行後面 {}
內的程式碼。
func 搭雲霄飛車(身高: Int) {
guard 身高 >= 140 else {
print("身高未滿 140 公分,不能搭乘!")
return
}
print("可以搭乘雲霄飛車")
}
這邊使用簡單的 function 來解釋上述這個例子,在 搭雲霄飛車(身高:)
這個方法中,檢查身高是否有達到 140 公分,如果身高大於等於 140 公分,程式會直接跳到 }
,往下執行,要不然就會進入 else {}
,執行裡面的程式碼,並且 return 出去。
return 出去?是要出去哪裡?
在使用 guard 的時候,else {}
判斷區塊必須跳離當前或是整個控制流程,這邊就必須使用到 Control transfer statements。
前面幾章有提到 break
或是 continue
,來轉換程式碼流程,像這類的語句就稱為控制轉移語句( Control transfer statements )。
在 Swift 中的針對流程控制轉移語句有很多,這邊先來簡單介紹一下幾個:
continue
break
fallthrough
return
throw
在迴圈中,可以使用 continue 跳過當次的迴圈,但不是跳出整個迴圈,還在控制流程中。
continue
只能用於迴圈for i in 1...5 {
if i == 3 { continue }
print("第 \(i) 次")
}
/*
Prints:
第 1 次
第 2 次
第 4 次
第 5 次
*/
從上面範例可以發現,少了 第 3 次
,因為在 i == 3
的時候,使用了 continue
跳過當次的迴圈,所以就不會往下執行了,結束當次迴圈。
break 可用來跳出整個迴圈,立即結束整個控制流程。
break
可用於迴圈或是 Switch-Case
for i in 1...5 {
if i == 3 { break }
print("第 \(i) 次")
}
/*
Prints:
第 1 次
第 2 次
*/
因為在 i == 3
時,使用了 break
中斷整個控制流程,所以就不會再繼續執行迴圈了,同樣的也可以使用在 Switch-Case
:
let 分數 = 59
switch 分數 {
case 100:
print("滿分")
case 60..<100:
print("及格")
default:
if 分數 == 59 {
print("補考")
break
}
print("死當")
}
在分數低於 60 分時,應該會印出死當,但如果是 59 分的時候,總是要給點機會,所以會印出 補考
然後中斷整個控制流程,所以就不會印出死當了。
還記得上一篇提到 Swift 的 Switch 有別於其他程式語言,Switch 不會貫穿,而是找到第一個符合的 case 就會終止整個控制流程,但如果我們還是想讓他繼續往下判斷,我們就可以在 case 中加入 fallthrough
語句。
fallthrough
只能用於 Switch-Case
let value = 120
switch value {
case let value where value.isMultiple(of: 2):
print("\(value) 是 2 的倍數")
fallthrough
case let value where value.isMultiple(of: 3):
print("\(value) 是 3 的倍數")
fallthrough
default:
print("此為整數")
}
/*
Prints:
120 是 2 的倍數
120 是 3 的倍數
此為整數
*/
isMultiple(of: 2)
用來判斷是否為 2 的倍數。
上面這個例子,在第一個 case 就已經匹配了,但是因為有 fallthrough
所以繼續往下判斷,第二個 case 又有 fallthrough
所以會再繼續往下判斷直到 default
。
但有一個地方要注意:假使你在 case 一開始就直接使用 fallthrough
,在編譯的時候,Xcode 會跳出警告訊息,該 case 在 fallthrough
後的所有程式碼將不會被執行,因為他會直接跳到下一個 case 判斷。
return 其實只用於跳出 functions
,但是這邊還沒介紹到 functions,所以我們先對他有個初步的認識,他可以用於 functions
中,主要的工作就是回傳值或是單純跳出當前的方法。
throw 也是一樣,在這一章節不會詳細介紹,但可以先簡單介紹,假使我們已經預設會有幾個 Error Situation 發生,我們可以在控制流程中加入 throw 來拋出錯誤,進而處理這些錯誤。
還記得我們在《 Day 6 | Swift 特別型別:Optionals 》中有提到如何安全地解開 Optional 型別,用的就是 if let
,guard 與 if 特別相似,在 guard 也是可以使用 guard let 來宣告常數,但是這裡的常數就不是一個臨時常數了,讓我們來看個範例:
func 吃宵夜(食物: String?) {
guard let 宵夜 = 食物 else { return }
print("今晚,我想來點 \(宵夜)")
}
上面這個範例,在 吃宵夜()
的方法中,宣告了一個常數叫做 宵夜
來接收一個 Optional 的參數 食物
,透過 guard let ... else
的方式,我們安全地解開來並且使用,但為什麼可以這樣做?
上面這句話可以這樣來解讀:
食物
這個參數是有值的,所以在這情況下,我將他指派給 宵夜
這個常數,以用來傳遞或是讀取,但假定參數 食物
是 nil,則會 return 出去。