通過在想調用的屬性、方法、或子腳本的可選值(optional value)(非空)后面放一個問號,可以定義一個可選鏈。這一點很像在可選值后面放一個嘆號來強制拆得其封包內的值。它們的主要的區(qū)別在于當可選值為空時可選鏈即刻失敗,然而一般的強制解析將會引發(fā)運行時錯誤。
為了反映可選鏈可以調用空(nil),不論你調用的屬性、方法、子腳本等返回的值是不是可選值,它的返回結果都是一個可選值。你可以利用這個返回值來檢測你的可選鏈是否調用成功,有返回值即成功,返回nil則失敗。
調用可選鏈的返回結果與原本的返回結果具有相同的類型,但是原本的返回結果被包裝成了一個可選值,當可選鏈調用成功時,一個應該返回Int的屬性將會返回Int?。
下面幾段代碼將解釋可選鏈和強制解析的不同。
首先定義兩個類Person和Residence。
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
Residence具有一個Int類型的numberOfRooms,其值為 1。Person具有一個可選residence屬性,它的類型是Residence?。
如果你創(chuàng)建一個新的Person實例,它的residence屬性由于是被定義為可選型的,此屬性將默認初始化為空:
let john = Person()
如果你想使用感嘆號(!)強制解析獲得這個人residence屬性numberOfRooms屬性值,將會引發(fā)運行時錯誤,因為這時沒有可以供解析的residence值。
let roomCount = john.residence!.numberOfRooms
//將導致運行時錯誤
當john.residence不是nil時,會運行通過,且會將roomCount 設置為一個int類型的合理值。然而,如上所述,當residence為空時,這個代碼將會導致運行時錯誤。
可選鏈提供了一種另一種獲得numberOfRooms的方法。利用可選鏈,使用問號來代替原來!的位置:
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的值。
因為這種嘗試獲得numberOfRooms的操作有可能失敗,可選鏈會返回Int?類型值,或者稱作“可選Int”。當residence是空的時候(上例),選擇Int將會為空,因此會出先無法訪問numberOfRooms的情況。
要注意的是,即使numberOfRooms是非可選Int(Int?)時這一點也成立。只要是通過可選鏈的請求就意味著最后numberOfRooms總是返回一個Int?而不是Int。
你可以自己定義一個Residence實例給john.residence,這樣它就不再為空了:
上一篇:Swift do...while循環(huán)下一篇:Swift默認構造器