國外優(yōu)秀教程精譯 | Swift 可選值詳解(上)

英文原文

Swift 是一門非常安全的語言,這里指的是 Swift 在防止代碼意外崩潰方面做了很多努力。
代碼崩潰的一個常見原因是試圖使用一個已損壞的或不存在的數(shù)據(jù)。舉例來說,假設有一個方法:

func getHaterStatus() -> String {
return "Hate"
}

該方法沒有任何參數(shù),并且返回一個 string:“Hate”。然而有一天陽光明媚,這些心有怨恨的家伙們不感到怨恨了——會發(fā)生什么事?我們可能就不想返回任何東西了:畢竟這些人今天不怨恨了嘛。
這時,一個空字符串也許是最好用來表明“沒啥事”的,有時這也是事實。但是用數(shù)字如何表現(xiàn)“什么都沒有”—— 用 0 表示“空數(shù)字”還是 -1 ?
別急著定義你自己的表示規(guī)則,Swift 已經(jīng)有了解決方案:可選值??蛇x值就是可能有值也可能沒有值的變量。大多數(shù)人都覺得可選值很難理解,別擔心——我將用各種方式來說明它,總有一種方式適合你。
當使用 -> String 時,表示“這個方法會返回一個確定的 string ”,即表示該方法不會返回空值,因此它被稱為安全的,因為你總是能獲得一個值,這個值類型是 string 。反之,如果方法可能返回有值或空值,需要改寫為下面這樣:

func getHaterStatus() -> String? {
    return "Hate"
}

注意這個額外的問號 String? 代表“可選的 string ”。當前的代碼無論如何都會返回 “Hate”,讓我們來修改一下:如果天氣晴朗,懷恨者們將展開新的生活篇章,放棄他們仇恨的生活,因此返回空值。在 Swift 中,空值有特別的關鍵字: nil。
于是代碼改為這樣:

func getHaterStatus(weather: String) -> String? {
    if weather == "sunny" {
        return nil
    } else {
        return "Hate"
    }
}

方法接受一個 string 參數(shù)(天氣 weather )并返回一個 string (仇恨狀態(tài)),但返回值可能有也可能沒有——為 nil 。具體到本文例子中,就表示我們可能得到一個 string ,或者得到 nil 。
那么重點來了:Swift 希望你的代碼是真正安全的,使用 nil 就不是一個好主意。它會使你的代碼崩潰,混淆你的代碼邏輯,或者在界面上顯示錯誤的內容。因此,當聲明一個值為可選值之時,Swift 就要確保你能安全地處理它。
試著把下面這行添加到你的 playground :

var status: String
status = getHaterStatus(weather: "rainy")

第一行創(chuàng)建一個 string 型變量,第二行把 getHaterStatus()的返回值賦值給這個變量——參數(shù)表示今天下雨,這樣可以保證仇恨者們正在仇恨中(返回值是"Hate”)。
這段代碼無法運行,因為我們聲明的 String 型變量 status 要求一個值,但getHaterStatus()可能無法提供,因為它返回可選值。也就是說,我們表示 status 一定是個 string ,但實際上 getHaterStatus()可能啥也不返回。Swift 根本不會讓你犯這個錯誤,這非常有用,因為它有效地阻止了一大堆常見錯誤。
為了解決這個問題,我們需要把 status聲明為 String?,或者干脆移除類型聲明,讓 Swift 自己推斷類型。第一種方法如下:

var status: String?
status = getHaterStatus(weather: "rainy")

第二種方式:

var status = getHaterStatus(weather: "rainy")

無論選擇哪個,值都可能為空值,Swift 是不會讓你冒險使用的。舉例來說,假設有這么一個方法:

func takeHaterAction(status: String) {
    if status == "Hate" {
        print("Hating")
    }
}

這段代碼接受一個 string ,根據(jù) string 內容打印一條消息。這個方法接受一個 String 值,卻不是 String?——你無法傳遞一個可選值給它,它需要一個確切的值,導致無法把 status 變量傳給它。
Swift 有兩個解決辦法。兩個都能用,但只能二選一。第一個解決方案是解包,它在條件語句中使用特定的語法規(guī)則。解包一次性做兩件事情:檢查可選值是否有值,如果有值就將其放入一個非可選值中并運行對應代碼塊。
解包語法如下:

if let unwrappedStatus = status {
    // unwrappedStatus 是非可選值
} else {
    // 解包失敗的處理
}

if let在一行代碼中簡潔地處理了檢查和解包,這種方法非常常見。應用這種方法,我們能安全地把 getHaterStatus() 解包,并僅在非可選 string 有效存在時,才調用 takeHaterAction()
這是完整代碼:

func getHaterStatus(weather: String) -> String? {
    if weather == "sunny" {
        return nil
    } else {
        return "Hate"
    }
}

func takeHaterAction(status: String) {
    if status == "Hate" {
        print("Hating")
    }
}

if let haterStatus = getHaterStatus(weather: "rainy") {
    takeHaterAction(status: haterStatus)
}

繼續(xù)閱讀

國外優(yōu)秀教程精譯 | Swift 可選值詳解(下)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,146評論 2 9
  • 基礎部分(The Basics) 當推斷浮點數(shù)的類型時,Swift 總是會選擇Double而不是Float。 結合...
    gamper閱讀 1,496評論 0 7
  • Swift 是一門開發(fā) iOS, macOS, watchOS 和 tvOS 應用的新語言。然而,如果你有 C 或...
    XLsn0w閱讀 990評論 2 1
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 15,423評論 4 61
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,199評論 1 10

友情鏈接更多精彩內容