可選鏈
- 官方的說法是:由多個可選類型組成的一個鏈條被稱為可選鏈
- 然而他的可選性實際上體現(xiàn)在:我們當(dāng)前調(diào)用的目標(biāo)可能為空.在我們調(diào)用這個目標(biāo)的時候,如果這個目標(biāo)有值則調(diào)用成功,如果目標(biāo)沒有值,則返回nil
可選鏈的表現(xiàn)形式:
變量名?.變量名?.變量名
可選鏈的實現(xiàn)細(xì)節(jié)
我們先創(chuàng)建幾個類,并讓這幾個類之間產(chǎn)生一定的關(guān)系,以此作為例子,來看一下可選鏈的賦值/取值/調(diào)用函數(shù)是如何實現(xiàn)的
class Father {
var name = ""
var child : Child? //父親有一個孩子
}
class Child {
var name = ""
var book : Book? //孩子有一本書
func readBook(){
print("孩子在努力的讀書")
}
}
class Book {
var name = "" //書有自己的名字
}
-
利用可選鏈取值
在可選鏈的取值過程中,編譯器會自動判斷每一個可選類型是否有值,如果可選類型有值,那么系統(tǒng)會自動進(jìn)行解包,如果發(fā)現(xiàn)可選類型沒有值,那么系統(tǒng)會自動返回一個nil
例:取出父親的孩子的書的名字
//實例化父親/孩子/書
let father = Father()
let child = Child()
let book = Book()
//建立三者之間的關(guān)系
father.child = child //父親的孩子是Child()
child.book = book //孩子的書是Book()
book.name = "Swifter" //書的名字是"Swifter"
print(father.child?.book?.name) //可選鏈的取值結(jié)果:Optional(Swifter)
Tips:關(guān)于可選鏈的自動解包
實際上,"father.child?.book?.name"這個鏈條就已經(jīng)足以證實可選鏈的自動解包功能.
這是因為,如果child沒有被自動解包,那么他的類型是Optional類型(而不是Child類型),
那么child就不可能調(diào)用Child類型中的book屬性
反例:取出父親的孩子的書的名字
//實例化父親/孩子/書
let father = Father()
let child = Child()
let book = Book()
//建立三者之間的關(guān)系
father.child = child //父親的孩子是Child()
// child.book = book //孩子的書是Book()
book.name = "Swifter" //書的名字是"Swifter"
print(father.child?.book?.name) //可選鏈的取值結(jié)果:nil
key message:
可見,任意一個環(huán)節(jié)為空的可選值為nil,整個可選鏈的返回值就為nil
-
利用可選鏈賦值
在可選鏈的賦值過程中,編譯器會自動判斷每一個可選類型是否有值,任意一個環(huán)節(jié)返回值為nil,則整條語句相當(dāng)于沒有執(zhí)行,如果所有的可選類型都有值,則系統(tǒng)會自動給可選類型進(jìn)行解包,解包之后再進(jìn)行賦值
例:給父親的孩子買一本書
//實例化父親/孩子/書
let father = Father()
let child = Child()
let book = Book()
//建立三者之間的關(guān)系
father.child = child //父親的孩子是Child()
child.book = book //孩子的書是Book()
father.child?.book?.name = "Swifter 3.0" //給可選鏈賦值
print(father.child?.book?.name) //可選鏈的取值結(jié)果:Swifter 3.0
反例:給父親的孩子買一本書
//實例化父親/孩子/書
let father = Father()
let child = Child()
let book = Book()
//建立三者之間的關(guān)系
father.child = child //父親的孩子是Child()
// child.book = book //孩子的書是Book()
father.child?.book?.name = "Swifter 3.0"
print(father.child?.book?.name) //可選鏈的取值結(jié)果:nil
-
利用可選鏈調(diào)用函數(shù)
在可選鏈調(diào)用函數(shù)的過程中,如果可選鏈中所有的可選類型都有值,則調(diào)用函數(shù)成功,如果可選鏈中的某一個可選類型的返回值為nil,則該函數(shù)不會被調(diào)用(并不會報錯)
例:父親讓孩子讀書
//實例化父親/孩子/書
let father = Father()
let child = Child()
//建立三者之間的關(guān)系
father.child = child //父親的孩子是Child()
father.child?.readBook() //結(jié)果:函數(shù)被調(diào)用,控制臺打印:孩子在努力的讀書
反例:父親讓孩子讀書
//實例化父親/孩子/書
let father = Father()
let child = Child()
//建立三者之間的關(guān)系
// father.child = child //父親的孩子是Child()
father.child?.readBook() //結(jié)果:函數(shù)不會被調(diào)用,控制臺無響應(yīng)