Swift - 使用 guard let 避免 if 金字塔

約翰:「你看你看!我的 if 金字塔已經堆的這麼高了喔」

同事:「孩子,有病要看醫生,金字塔請用guard來解決,記得愛配溫開水」

在新需求不斷和舊功能來亂的愛恨揪葛中

讓新功能加進來之後,舊功能可以像往日一樣可愛穩定運作

這個神聖使命一直以來是我作為 Google 搜尋家兼記事本使用者奉為聖旨的

閒話不多說,如果今天我們要讓使用者輸入一連串的資料之後按下送出時檢查是否有空,如果通過了就正常呼叫API把資料打包存起來

辜且不討論為何不在欄位失焦(OnBlur)檢查,今天我們就是要使用者輸入之後按下按鈕後送出,那我們可能會有這樣的程式

@IBAction func submitButtonTapped(sender :UIButton) {
if let name = nameLabel.text {
    if let age = ageLabel.text {
        if let dob = dobLabel.text {
            if let gender = genderLabel.text {
                keepData(name,age,dob,gender)
            } else {
                writeLog("取性別時失敗了!")
            }
        } else {
            writeLog("取生日時失敗了!")
        }
    } else {
        writeLog("取年齡時失敗了!")
    }
} else {
    writeLog("取Name時失敗了!")
}
}

再整理一下可能可以這樣寫比較好讀

 

@IBAction func submitButtonTapped(sender :UIButton) {
    if let name = nameLabel.text, name == "" {
        writeLog("取姓名時失敗了!")
        return
    }
    if let age = ageLabel.text, age == "" {
        writeLog("取年齡時失敗了!")
        return
    }
    if let dob = dobLabel.text, dob == "" {
        writeLog("取生日時失敗了!")
        return
    }
    if let gender = genderLabel.text, gender == "" {
        writeLog("取性別時失敗了!")
        return
    }
    keepData(name.text!, age.text!, dob.text!, gender.text!)
}

這樣雖然也算ok了,不過有時我們就是想在檢查不通過時做點什麼事情,也同時把宣告的變數給留下的話我們可以這樣寫

@IBAction func submitButtonTapped(sender :UIButton) {
    guard let name = nameLabel.text, name != "" else {
        writeLog("取姓名時失敗了!")
        return
    }
    if let age = ageLabel.text, age == "" else {
        writeLog("取年齡時失敗了!")
        return
    }
    if let dob = dobLabel.text, dob == "" else {
        writeLog("取生日時失敗了!")
        return
    }
    if let gender = genderLabel.text, gender == "" else {
        writeLog("取性別時失敗了!")
        return
    }
    keepData(name, age, dob, gender)
}

這樣寫不僅增加了可讀性,日後也滿好維護的

所以,在未來Coding的路上,試著考慮考慮 guard let 的可能性吧!!!