Swift(二十一)可選鏈接

4f1c5f53cfd9d3f9e17289689dd1aa41906b755996615-FtSJ9i_fw658.jpeg

可選鏈接(自判斷鏈接)(Optional Chaining)是一種可以請(qǐng)求和調(diào)用屬性、方法及子腳本的過程,它的自判斷性體現(xiàn)于請(qǐng)求或調(diào)用的目標(biāo)當(dāng)前可能為空(nil)。如果自判斷的目標(biāo)有值,那么調(diào)用就會(huì)成功;相反,如果選擇的目標(biāo)為空(nil),則這種調(diào)用將返回空(nil)。多次請(qǐng)求或調(diào)用可以被鏈接在一起形成一個(gè)鏈,如果任何一個(gè)節(jié)點(diǎn)為空(nil)將導(dǎo)致整個(gè)鏈?zhǔn)А?/p>

簡單來說,就是被定義為可選類型的屬性,你在使用時(shí),不比強(qiáng)制解析,而是用可選鏈接,就是可選解析,因?yàn)?,可選類型可能為nil,如果你強(qiáng)制解析使用,則會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤

注意: Swift的可選鏈接和Objective-C中的消息為空有些相像,但是Swift可以使用在任意類型中,并且失敗與否可以被檢測(cè)到。

可選鏈接可替代強(qiáng)制拆包
通過在想調(diào)用的屬性、方法、或子腳本的自判斷值(optional value)(非空)后面放一個(gè)問號(hào),可以定義一個(gè)自判斷鏈接。這一點(diǎn)很像在自判斷值后面放一個(gè)聲明符號(hào)來強(qiáng)制拆得其封包內(nèi)的值。他們的主要的區(qū)別在于當(dāng)自判斷值為空時(shí)可選鏈接即刻失敗,然而一般的強(qiáng)制拆包將會(huì)引發(fā)運(yùn)行時(shí)錯(cuò)誤。

為了反映可選鏈接可以調(diào)用空(nil),不論你調(diào)用的屬性、方法、子腳本等返回的值是不是自判斷值,它的返回結(jié)果都是一個(gè)自判斷值。你可以利用這個(gè)返回值來檢測(cè)你的自判斷鏈接是否調(diào)用成功,有返回值即成功,返回nil則失敗。

調(diào)用可選鏈接的返回結(jié)果與原本的返回結(jié)果具有相同的類型,但是原本的返回結(jié)果被包裝成了一個(gè)自判斷值,當(dāng)可選鏈接調(diào)用成功時(shí),一個(gè)應(yīng)該返回Int的屬性將會(huì)返回Int?。

下面幾段代碼將解釋可選鏈接和強(qiáng)制拆包的不同。
首先定義兩個(gè)類Person和Residence。

class Person { 
var residence: Residence? 
} 
  
class Residence { 
var numberOfRooms = 1 
} 

如果你創(chuàng)建一個(gè)新的Person實(shí)例,它的residence屬性由于是被定義為自判斷型的,此屬性將默認(rèn)初始化為空:

let john = Person() 

如果你想使用聲明符!強(qiáng)制拆包獲得這個(gè)人residence屬性numberOfRooms屬性值,將會(huì)引發(fā)運(yùn)行時(shí)錯(cuò)誤,因?yàn)檫@時(shí)沒有可以供拆包的residence值。

//fatal error: unexpectedly found nil while unwrapping an Optional value
//拆包錯(cuò)誤,因?yàn)榭蛇x類型的值為nil
let roomCount = john.residence!.numberOfRooms 

接下來我們使用可選鏈接,解析時(shí)把!改成?

//這告訴Swift來鏈接自判斷residence?屬性,如果residence存在則取回numberOfRooms的值。
let roomCount = john.residence?.numberOfRooms
print(roomCount ?? 5)  //這種打印方法是當(dāng)roomCount為空時(shí),給一個(gè)默認(rèn)值5

因?yàn)檫@種嘗試獲得numberOfRooms的操作有可能失敗,自判斷鏈接會(huì)返回Int?類型值,或者稱作“可選Int”。當(dāng)residence是空的時(shí)候(上例),選擇Int將會(huì)為空,因此會(huì)出先無法訪問numberOfRooms的情況。

你可以自己定義一個(gè)Residence實(shí)例給john.residence,這樣它就不再為空了:

john.residence = Residence() 
//john.residence 現(xiàn)在有了實(shí)際存在的實(shí)例而不是nil了。如果你想使用和前面一樣的自判斷鏈接來獲得numberOfRoooms,它將返回一個(gè)包含默認(rèn)值1的Int?: 
  
if let roomCount = john.residence?.numberOfRooms { 
    print("John's residence has \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\(roomCount) room(s).") 
} else { 
    print("Unable to retrieve the number of rooms.") 
} 
// 打印 "John's residence has 1 room(s)"。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 126.析構(gòu)器 在一個(gè)類實(shí)例銷毀前,一個(gè)析構(gòu)器會(huì)立即調(diào)用。使用deinit 關(guān)鍵字來表示析構(gòu)器, 跟構(gòu)造器寫法類似...
    無灃閱讀 907評(píng)論 0 4
  • 本章將會(huì)介紹 自動(dòng)引用計(jì)數(shù)的工作機(jī)制自動(dòng)引用計(jì)數(shù)實(shí)踐類實(shí)例之間的循環(huán)強(qiáng)引用解決實(shí)例之間的循環(huán)強(qiáng)引用閉包引起的循環(huán)強(qiáng)...
    寒橋閱讀 1,035評(píng)論 0 0
  • 可選鏈(Optional Chaining)是一種可以請(qǐng)求和調(diào)用屬性、方法和子腳本的過程,用于請(qǐng)求或調(diào)用的目標(biāo)可能...
    零度_不結(jié)冰閱讀 368評(píng)論 0 0
  • 官方文檔鏈接 原文鏈接 可選鏈(Optional Chaining)是為了在一個(gè)可能當(dāng)前值為nil的optiona...
    hrscy閱讀 412評(píng)論 0 3
  • 初春的繁花似錦帶來的美好意境逐漸被燥熱所取代,那青草的鵝黃也刷成了翠綠,蒼松翠柏的顏色也不那么顯眼了。泯然于這...
    幽小窗閱讀 579評(píng)論 4 10

友情鏈接更多精彩內(nèi)容