iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0

Conditional Statement - Guard

你知道除了使用 If 來進行條件判斷外,還可以使用 Guard 嗎?


Guard

在條件判斷除了 IfSwitch,還有一種判斷方式跟 If 很像,那就是 Guard

先來看一下 Guard 的使用方式:

guard 條件 else {
	...
}

Guard 一樣是透過 Boolean 來判斷條件,但是跟 If 不太一樣的地方是,Gurad 結尾都必須加上 else,如果條件不成立就會執行後面 {} 內的程式碼。

func 搭雲霄飛車(身高: Int) {
    guard 身高 >= 140 else {
        print("身高未滿 140 公分,不能搭乘!")
        return
    }
    
    print("可以搭乘雲霄飛車")
}

這邊使用簡單的 function 來解釋上述這個例子,在 搭雲霄飛車(身高:) 這個方法中,檢查身高是否有達到 140 公分,如果身高大於等於 140 公分,程式會直接跳到 },往下執行,要不然就會進入 else {},執行裡面的程式碼,並且 return 出去。

小知識 1:Control transfer statements

return 出去?是要出去哪裡?

在使用 guard 的時候,else {} 判斷區塊必須跳離當前或是整個控制流程,這邊就必須使用到 Control transfer statements

前面幾章有提到 break 或是 continue,來轉換程式碼流程,像這類的語句就稱為控制轉移語句( Control transfer statements )

在 Swift 中的針對流程控制轉移語句有很多,這邊先來簡單介紹一下幾個:

  • continue
  • break
  • fallthrough
  • return
  • throw

continue

在迴圈中,可以使用 continue 跳過當次的迴圈,但不是跳出整個迴圈,還在控制流程中。

  • continue 只能用於迴圈
for i in 1...5 {
	if i == 3 { continue }
	print("第 \(i) 次")
}

/*
Prints:
第 1 次
第 2 次
第 4 次
第 5 次
*/

從上面範例可以發現,少了 第 3 次,因為在 i == 3 的時候,使用了 continue 跳過當次的迴圈,所以就不會往下執行了,結束當次迴圈。

break

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 分的時候,總是要給點機會,所以會印出 補考 然後中斷整個控制流程,所以就不會印出死當了。

fallthrough

還記得上一篇提到 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 判斷

https://ithelp.ithome.com.tw/upload/images/20200915/20118283rCAzO2z41N.png

return、throw

return 其實只用於跳出 functions,但是這邊還沒介紹到 functions,所以我們先對他有個初步的認識,他可以用於 functions 中,主要的工作就是回傳值或是單純跳出當前的方法。

throw 也是一樣,在這一章節不會詳細介紹,但可以先簡單介紹,假使我們已經預設會有幾個 Error Situation 發生,我們可以在控制流程中加入 throw 來拋出錯誤,進而處理這些錯誤。

小知識 2:guard let ... else

還記得我們在《 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 出去。

上一篇
Day 14 | Swift 流程控制:If 和 Switch
下一篇
Day 16 | Swift Functions (1)
系列文
給我 30 天,給你一輩子:Swift 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言