位置:首頁 > 高級語言 > Swift教學 > Swift可選鏈可替代強製解析

Swift可選鏈可替代強製解析

可選鏈可替代強製解析

通過在想調用的屬性、方法、或子腳本的可選值(optional value)(非空)後麵放一個問號,可以定義一個可選鏈。這一點很像在可選值後麵放一個歎號來強製拆得其封包內的值。它們的主要的區彆在於當可選值為空時可選鏈即刻失敗,然而一般的強製解析將會引發運行時錯誤。

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

調用可選鏈的返回結果與原本的返回結果具有相同的類型,但是原本的返回結果被包裝成了一個可選值,當可選鏈調用成功時,一個應該返回Int的屬性將會返回Int?

下麵幾段代碼將解釋可選鏈和強製解析的不同。

首先定義兩個類PersonResidence

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

Residence具有一個Int類型的numberOfRooms,其值為 1。Person具有一個可選residence屬性,它的類型是Residence?

如果你創建一個新的Person實例,它的residence屬性由於是被定義為可選型的,此屬性將默認初始化為空:

let john = Person()

如果你想使用感歎號(!)強製解析獲得這個人residence屬性numberOfRooms屬性值,將會引發運行時錯誤,因為這時冇有可以供解析的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,這樣它就不再為空了:

john.residence = Residence()

john.residence 現在有了實際存在的實例而不是nil了。如果你想使用和前麵一樣的可選鏈來獲得numberOfRoooms,它將返回一個包含默認值 1 的Int?

if let roomCount = john.residence?.numberOfRooms {
    println("John's residence has \(roomCount) room(s).")
} else {
    println("Unable to retrieve the number of rooms.")
}
// 打印 "John's residence has 1 room(s)"。