檢查條件是否成立,不成立就離開的 guard else

guard else 的語法和作用和 if else 很像,但卻有一些不同的地方,讓我們透過以下的 function motherSay 說明。

guard else 語法說明

func motherSay(age: Int) {   guard age > 18 else {      print("18 歲以下要乖乖唸書")      return   }   print("18 歲以上,可以盡情談戀愛")}

guard 跟 if 一樣,後面都是接結果為 true 或 false 的條件,但 guard 卻有以下幾點不同之處:

  • guard 喜歡依賴別人,不能沒有 else。
在輸入程式時,只要記得搭配 Xcode 的自動完成,選擇選單裡的 guard — Swift Guard Statement,Xcode 將幫我們自動補上 else。
  • guard 後專門描述我們希望成立的條件。當條件成立時,程式將離開 guard 搭配的 else { },繼續往下執行我們希望條件成立時做的事。
  • 當 guard 的條件不成立時,將執行 else { } 的程式。
  • else { } 的程式執行後,必須離開 guard 所在區塊,如此才不會繼續往下執行條件成立時要做的事。就像剛剛的例子,我們利用 return 離開 function motherSay。
else 的 { } 裡忘了加 return 離開,因此產生紅色錯誤

因此剛剛的 function motherSay,我們在 guard 之後描述談戀愛須滿足的必要條件,age 必須大於 18 。

當 age 超過 18 時,將印出 18 歲以上,可以盡情談戀愛

motherSay(age: 25)

當 age 小於 18 時,將執行 else { } 的程式,印出 18 歲以下要乖乖唸書

motherSay(age: 10)

guard else { } 裡除了搭配 return,有時也可以搭配 break,continue 或 throw,只要能讓它不會繼續往下執行條件成立時要做的事 ,比方以下寫在 for 裡的 guard 例子。

搭配 break

func motherSay(ages: [Int]) {   for age in ages {      guard age > 18 else {         print("18 歲以下要乖乖唸書")         break      }      print("18 歲以上,可以盡情談戀愛")   }}motherSay(ages: [25, 10, 20])

搭配 continue

func motherSay(ages: [Int]) {   for age in ages {      guard age > 18 else {         print("18 歲以下要乖乖唸書")         continue      }      print("18 歲以上,可以盡情談戀愛")   }}motherSay(ages: [25, 10, 20])

由於 guard else 和 if else 十分相像,所以 guard else 也可以搭配多重條件,例如以下例子:

年紀 > 18 並且體重超過 40,才能談戀愛

func motherSay(age: Int, weight: Int) {   guard age > 18, weight > 40 else {      print("年紀不夠大,體重太輕,只能乖乖唸書")      return   }   print("夠成熟夠穩重,可以盡情談戀愛")}

年紀 > 18,或存款超過 10000 即可談戀愛

func motherSay(age: Int, money: Int) {   guard age > 18 || money > 10000 else {      print("年紀不夠大,或是錢太少,只能乖乖唸書")      return   }   print("夠成或夠有錢熟,可以盡情談戀愛")}

guard else 語法的優點

看來 guard else 的功能似乎跟 if else 大同小異,為什麼 Swift 還要多此一舉,發明 guard else 呢?在某些情況,guard else 的寫法比 if else 更好,它將帶來以下幾點好處:

  • 程式的意思更清楚,可讀性更好。

guard 後面描述我們希望成立的條件,比方對象的年紀條件在 18 ~ 30 歲之間,所以程式的意思會更清楚,不像 if 後面可能描述我們希望成立的條件,也可能描述我們希望不成立的條件。

  • 實現提早離開(early exit)的效果,不會浪費時間執行用不到的程式。

在 App 的表單輸入頁面,guard 很適合用來檢查欄位。比方我們做了一個通訊錄 App, 在新增聯絡人時,程式須做許多檢查,像是名字是否忘了輸入,email 格式是否有錯等。確認每個欄位都 ok 後,才能完成新增聯絡人的動作,若有某個欄位出錯,應該跳出錯誤提醒使用者。

因此,如果發現名字有問題,應該不要再浪費時間執行接下來的程式,而 guard 正是幫我們實現此功能的好幫手。假設新增聯絡人的欄位有十個,我們可用十個 guard 檢查,一旦某個 guard 出錯即顯示錯誤,不再往下執行。唯有通過十個 guard 的層層考驗,才會執行最後新增聯絡人的動作。

func addContact(name: String, age: Int) {   guard name.isEmpty == false else {      print("請輸入名字")      return   }   guard age >= 1 else {      print("未滿 1 歲,不夠格當朋友")      return   }   // 以下區塊可加入新增聯絡人的程式碼   print("新增聯絡人")}addContact(name: "彼得潘", age: 20)

若將剛剛的 function addContact 改用 if else 的寫法,將如下圖所示,很難一眼看出新增聯絡人的程式寫在哪。相反的,guard 的寫法將十分清楚,一眼就能看出它落在通過重重 guard 考驗後的段落。

func addContact(name: String, age: Int) {   if name.isEmpty {      print("請輸入名字")   } else {      if age < 1 {         print("未滿 1 歲,不夠格當朋友")      } else {         // 以下區塊可加入新增聯絡人的程式碼         print("新增聯絡人")      }   }}

除了基本的 guard else,guard 也常跟 let 搭配,組成檢查 optional 是否有值的 guard let 語法,相關說明可參考以下連結。

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
彼得潘的 iOS App Neverland

彼得潘的 iOS App Neverland

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com