空值(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]