swift 語言的基礎 - nil / optional / unwrap

  1. 空值(nil)/ optional(?) / unwrap(!)
    1. 什麼是空值
    2. why Optional
      1. 範例
    3. optional ? 的特性
    4. 現實生活中的型別安全

空值(nil)/ optional(?) / unwrap(!)

什麼是空值

如果要舉一個生活中的例子,程式裡的變數,就像是一個裝著鞋子的鞋盒(optional),變數裡面的值,就是鞋子。程式在運作或傳遞變數時,是將鞋盒傳來傳去,如果需要對值做一些變化的時候,才會把鞋子從鞋盒拿出來(wrap),整理好再放回去鞋盒裡去。如果鞋盒裡沒有鞋子(nil),那麼,執恴要把鞋子給拿出來,就會造成程式執行錯誤,或者是crash。

why Optional

程式在取用變數時,有一定的機率會遇到變收尚未初始化或尚未賦值,程式取不到值,而發生異常或是直接CRASH的狀況發生,為了防止意外,可以假設設定每個變數都有可以是不存的,所以就會在型別的後綴加一個問題,來表示 optional, 100% 確定有值的,就不用 optional, 就可以用很快的速度,不一一檢查變數,直接執行程式。

範例

Int? i = 1
String? s = "aaa"
Double? d = 0.1

在確定有值的時候,(強迫?)取值的方式為

print(i!)
//output   1

print(s!)
//output   "aaa"

print(d!)
//output   0.1

如果不加(!),取值的結果就會不一樣

print(i)
//output    optional(1)

print(s)
//output    optional("sss")

print(d)
//output    optional(0.1)

optional ? 的特性

如果在等號的左邊有個?,那麼如果變數為 nil 時, 則整行不會被執行


var abc = nil

abc?.text = "123" //將不會執行

現實生活中的型別安全

那麼,到底什麼時候要用 optional,什麼時候不用呢? 舉個生活中的例子來說,手機APP裡,使用 http request 與 伺服器端溝通, 當收到 API 的http response, 大部份是回覆 json 格式的 response, 手機再接著畫出UI的呈現。但是,server api 其實沒想像中的可靠,萬一少回了一個欄位呢?,萬一回的欄位的型別不對了呢?所以,只要是未知的變數,絕大部份都會做型別安全的保護,讓程式不會因為壞掉而無法繼續運作。

以下有幾種不同的 optional binding寫法

範例 1

String? s = "aaa"

if s != nil {
    //如果鞋盒裡有鞋子的話, 就拿出來,並且命名為 s1,
    //s1 在這個 code block 的生命週期裡,就隨時可取用,不用擔心程式爆炸 
} else {
    //鞋盒裡沒有鞋子,不要想了
}

範例 2

String? s = "aaa"

if let s1 = s {
    //如果鞋盒裡有鞋子的話, 就拿出來,並且命名為 s1,
    //s1 在這個 code block 的生命週期裡,就隨時可取用,不用擔心程式爆炸 
} else {
    //鞋盒裡沒有鞋子,不要想了
}

範例 3

String? s = "aaa"

guard let s1 = s else {
    //鞋盒裡沒有鞋子,不要繼續了
    return
}
    
//s1 在這個 guard let 之後,就隨時可取用,不用擔心程式爆炸 

範例 4

Nil-coalescing operator

String? s = "aaa"

let s1 : String = s ?? ""

如果 s 不是 nil 的話。則 s1 = s 裡的值。不然的話。s1是預設值 “” ( 空字串 )

然後 s1 就有值了, 不管是不是 s 鞋盒裡的值, 但至少不會壞掉。


轉載請註明來源,歡迎對文章中的引用來源進行考證,歡迎指出任何有錯誤或不夠清晰的表達。可以郵件至 [email protected]