
使用可選值有時(shí)會(huì)讓人感到有點(diǎn)笨拙,所有的解包和檢查會(huì)變得如此繁重,以至于會(huì)讓你想要丟幾個(gè)感嘆號(hào)上去強(qiáng)制解包,好讓你能繼續(xù)工作下去。但是請(qǐng)小心:如果你強(qiáng)制解包一個(gè)沒有值的可選值,你的代碼就崩了。
Swift 有兩個(gè)技術(shù)來幫助你減少代碼的復(fù)雜度。首要的就是可選鏈,它只允許在可選值有值時(shí)運(yùn)行代碼。讓我們來試試,復(fù)制下面的代碼到 playground :
func albumReleased(year: Int) -> String? {
switch year {
case 2006: return "Taylor Swift"
case 2008: return "Fearless"
case 2010: return "Speak Now"
case 2012: return "Red"
case 2014: return "1989"
default: return nil
}
}
let album = albumReleased(year: 2006)
print("The album is \(album)")
這段代碼將在調(diào)試窗口輸出 The album is Optional("Taylor Swift") 。
如果我們想將 albumReleased() 的返回值轉(zhuǎn)換為大寫(即輸出 TAYLOR SWIFT 而不是 Taylor Swift ),我們可以調(diào)用 string 的 uppercased() 方法。如下所示:
let str = "Hello world"
print(str.uppercased())
可問題是,albumReleased()返回的是一個(gè)可選 string : 它可能返回一個(gè) string ,也可能什么也不返回。所以,我們的實(shí)際意思是:如果我們得到一個(gè) string ,就轉(zhuǎn)為大寫,否則啥都別做。這就是可選鏈的用武之地了,因?yàn)樗吞峁┝诉@樣的能力。
試著把最后兩行代碼改成下面這樣:
let album = albumReleased(year: 2006)?.uppercased()
print("The album is \(album)")
注意這里有個(gè)“問號(hào)”,這就是可選鏈:在“問號(hào)”后的所有代碼,只會(huì)在“問號(hào)”前的代碼有值時(shí),才會(huì)運(yùn)行。這不會(huì)影響 album 的基本數(shù)據(jù)類型,因?yàn)闊o論這行返回 nil 還是大寫的 album 名稱,它都是一個(gè)可選 string 。
可選鏈可以是任意長(zhǎng)度,比如:
let album = albumReleased(year: 2006)?.someOptionalValue?.someOtherOptionalValue?.whatever
Swift 將會(huì)從左到右檢查它們,直到遇到一個(gè) nil 后停止。
nil 合并運(yùn)算符
其實(shí)這是 Swift 提供的一個(gè)簡(jiǎn)單功能,可以使你的代碼更簡(jiǎn)單、更安全,只不過名字起的有些夸張,讓人害怕它。這令人汗顏,如果你花時(shí)間弄明白 nil 合并運(yùn)算符,會(huì)使你的生活更輕松。
它起的作用就好像你會(huì)說“如果可以的話,使用 A 的值,如果 A 是 nil 的話就使用 B 的值?!彼鼘?duì)可選值特別有用,因?yàn)樗行ё柚沽怂鼈冏優(yōu)榭蛇x值,通過提供一個(gè)非可選值 B ,這樣以來,如果 A 是可選值并且有值,A 就被使用了。如果 A 沒有值, B 就被使用(這樣我們還是得到了值)。無論如何,我們都有(確定的)值了。
使用下面的代碼來實(shí)際體驗(yàn)一下:
let album = albumReleased(year: 2006) ?? "unknown"
print("The album is \(album)")
“雙引號(hào)”就是 nil 合并運(yùn)算符,在上面的代碼中,意味著“如果 albumReleased()返回一個(gè)值就賦值給變量 album ,如果返回 nil 就用 unknown 代替”。
現(xiàn)在你觀察一下輸出窗口,將輸出 “The album is Taylor Swift”,沒有多余的可選標(biāo)識(shí)(Optional("Taylor Swift"))。這是因?yàn)?Swift 現(xiàn)在能肯定可以獲得一個(gè)確定的值,不是方法返回的值就是你提供的unknown。這意味著你不需要冒險(xiǎn)解包任何東西,可以保證你有確定的數(shù)據(jù)可用,這使你的代碼更安全、更容易使用。
溪石翻譯筆記
- 如果將可選值賦值給一個(gè)變量,該變量也為可選值
- 強(qiáng)制解包(感嘆號(hào))可以獲得一個(gè)非可選值,但當(dāng)可選值為 nil 時(shí),會(huì)崩潰