通過在想調(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è)你的可選鏈?zhǔn)欠裾{(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
}
Residence具有一個(gè)Int類型的numberOfRooms,其值為 1。Person具有一個(gè)可選residence屬性,它的類型是Residence?。
如果你創(chuàng)建一個(gè)新的Person實(shí)例,它的residence屬性由于是被定義為可選型的,此屬性將默認(rèn)初始化為空:
let john = Person()
如果你想使用感嘆號(hào)(!)強(qiáng)制解析獲得這個(gè)人residence屬性numberOfRooms屬性值,將會(huì)引發(fā)運(yùn)行時(shí)錯(cuò)誤,因?yàn)檫@時(shí)沒有可以供解析的residence值。
let roomCount = john.residence!.numberOfRooms
//將導(dǎo)致運(yùn)行時(shí)錯(cuò)誤
當(dāng)john.residence不是nil時(shí),會(huì)運(yùn)行通過,且會(huì)將roomCount 設(shè)置為一個(gè)int類型的合理值。然而,如上所述,當(dāng)residence為空時(shí),這個(gè)代碼將會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。
可選鏈提供了一種另一種獲得numberOfRooms的方法。利用可選鏈,使用問號(hào)來代替原來!的位置:
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has \(roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// 打印 "Unable to retrieve the number of rooms.
這告訴 Swift 來鏈接可選residence?屬性,如果residence存在則取回numberOfRooms的值。
因?yàn)檫@種嘗試獲得numberOfRooms的操作有可能失敗,可選鏈會(huì)返回Int?類型值,或者稱作“可選Int”。當(dāng)residence是空的時(shí)候(上例),選擇Int將會(huì)為空,因此會(huì)出先無法訪問numberOfRooms的情況。
要注意的是,即使numberOfRooms是非可選Int(Int?)時(shí)這一點(diǎn)也成立。只要是通過可選鏈的請(qǐng)求就意味著最后numberOfRooms總是返回一個(gè)Int?而不是Int。
你可以自己定義一個(gè)Residence實(shí)例給john.residence,這樣它就不再為空了:
上一篇:Swift do...while循環(huán)下一篇:Swift默認(rèn)構(gòu)造器