swift中的可選類型(?)、強制解析(!)、自動解析、可選綁定、可選鏈


在這裏插入圖片描述

1. 前言

對於一直用OC的iOS開發者來說,swift的可選類型可算是個新東西。剛開始接觸swift的時候,(?), (!), (??)這些符號搞得我好暈,所以我覺得有必要整理出來,讓更多的人不暈!

2. 可選類型

2.1 啥叫可選類型?

就是Option類型,用(?)表示。被它修飾的變量,意味着這個變量可能有一個值,也有可能沒值 。(讓我想起了薛定諤的貓😊)
定義一個可選類型:

var optionalInteger: Int?
var optionalInteger: Optional<Int>

Int? == Optional<Int>
一般用Int?

2.2 可選類型是幹啥用的?

OC中是沒有可選類型的,那swift中爲甚就有了呢?

Swift是一種類型安全的語言,可選類型的引入可以讓我們的編碼變得更加安全。可選類型描述的對象可能有值可能沒值,就因爲有這種特性,swift的初衷就是希望我們編程者在使用對象的時候要做好對象檢測判斷,處理nil的情況。

例如,要從字典中取一個值,那麼有可能取成功了,也有可能沒有這個key。這個時候用可選類型接收結果就很好。

3. 強制解析

3.1 可選類型需要解析出真實值

在使用可選類型變量時,需要把它解析出來。當你確定可選類型確實包含值之後,你可以在可選的名字後面加一個感嘆號(!)來獲取值。這個感嘆號表示"我知道這個可選有值,請使用它。"

var myString:String? = "hello world!"
print("the string is \(myString!)")

3.2 強制解析nil會崩潰

可選類型變量如果爲空,用強制解析會導致程序崩潰。所以,在解析之前,我們(程序員)要確保它是有值得。
可以用一下代碼確保安全性:

var myString:String?
myString = "Hello, Swift!"
if myString != nil {
   // 強制解析
   print( myString! )
}else{
   print("myString 值爲 nil")
}

還有另一種更爲優雅的書寫方式,稱爲“可選綁定”。見下

4. 可選綁定

使用可選綁定(optional binding)來判斷可選類型是否包含值,如果包含就把值賦給一個臨時常量或者變量。可選綁定可以用在if和while語句中來對可選類型的值進行判斷並把值賦給一個常量或者變量。

var myString:String?
myString = "Hello, Swift!"
if let tempString = myString {
    print( tempString )
}else{
    print("tempString 值爲 nil")
}
輸出:"Hello, Swift!"

5. 自動解析

也叫隱式解析。你可以在聲明可選變量時使用感嘆號(!)替換問號(?)。這樣可選變量在使用時就不需要再加一個感嘆號(!)來獲取值,它會自動解析。

如果不用自動解析,只用強制解析,有可能代碼會是這樣:

var dog: String? = "wangcai"    //dog變量想要給一個非可選類型的cat變量賦值
let cat: String = dog!          //cat說,嗯,我已經拿到啦,麼麼噠!
let tiger: String = dog!        //hello,我是旺財~
let fish: String = dog!         //我是旺財~
let bird: String = dog!         //旺財。。。
let sheep: String = dog!        //爲什麼每次都得驗證一遍
let mouse: String = dog!        //心好累

看見沒,(!)滿屏都是。爲了不讓(!)滿屏飛,我們使用自動解析:

var dog: String! = "wangcai"    //dog變量想要給一個非可選類型的cat變量賦值
let cat: String = dog           //cat說,嗯,我已經拿到啦,麼麼噠!
let tiger: String = dog         //ok
let fish: String = dog          //ok
let bird: String = dog          //ok
let sheep: String = dog         //ok
let mouse: String = dog         //ok

好多了。

那麼我們是否一直使用隱式解析可選類型就萬事大吉了呢?答案是No。因爲隱式解析可選類型還是可選類型,它是可以爲空的。如果在空值時被使用,程序就會Crash。

如果是個常量,或者可以百分百確保一直有值,那麼自動解析就可以發揮優勢了。否則就不要用了。

6. 可選鏈

Swift 有一個特殊的機制,可選鏈,它用於在被嵌套的類或結構體中調用方法或訪問屬性。
這個在處理數據模型的時候非常有用。例如,有以下數據:

struct Order {
	let orderNumber: Int
	let person: Person?
}
struct Person {
	let name: String
	let address: Address?
}
struct Address {
	let streetName: String
	let city: String 
	let state: String?
}
let order = Order(orderNumber: 42, person: nil)

給定一個 Order,如何才能知道客戶地址中的 state 爲何值呢?我們可以使用顯式解包運算符:
order.person!.address!.state!
然而,如果任意中間數據缺失,這麼做可能會導致運行時異常,crash。使用可選綁定相對更安全:

if let person = order.person {
    if let address = person.address {
        if let state = address.state {
            print("Got a state: \(state)")
        }
    }
}

但這未免有些煩瑣,而且我們也沒有處理其他情況。若使用可選鏈,這個例子將會變成:

if let myState = order.person?.address?.state {
    print("This order will be shipped to \(myState)")
} else {
    print("Unknown person, address, or state.")
}

我們使用了問號運算符來嘗試對可選類型進行解包,而不是強制將它們解包。訪問任意屬性失敗時,都將會導致整條語句鏈返回 nil。

參考致謝:
Swift中的可選類型?和隱式解析可選類型!
論swift可選類型,玩轉可選值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章