在?Swift?中,使用可選類型(optionals)來表示值可能缺失的情況。可選屬性存在兩種可能性,一種是有值,你可以通過解包來訪問這個(gè)值。另一種是根本沒有值,即?nil?的情況。
Objective-C中并沒有可選類型這個(gè)概念。Objective-C中一般會(huì)通過返回一個(gè)特殊值(如:NSNotFound)來暗示值的缺失。
可選類型的聲明
通過在類型后面加一個(gè)問號(hào)(?)來標(biāo)記這個(gè)變量的值是可選的,通過將可選變量賦值為?nil?來表示它沒有值,如下:
varserverResponseCode:Int? =404
serverResponseCode = nil
注意:不能將非可選類型的變量和常量賦值為nil。
如果聲明一個(gè)可選類型的常量或變量,但是沒有賦值,它們會(huì)被自動(dòng)置為nil,如下:
varsurveyAnswer:String?// surveyAnswer 被自動(dòng)設(shè)置為 nil
注意:Swift 中的nil和 Objective-C 中的nil并不一樣。Objective-C 中的nil是一個(gè)指向不存在對(duì)象的指針。Swift中的nil不是指針--它是一個(gè)確定的值,用來表示值缺失。任何類型的可選狀態(tài)都可以被設(shè)置為nil,不只是對(duì)象類型。
可選類型解析
強(qiáng)制解析
使用 if 語(yǔ)句來判斷可選類型的值是否為空,即通過是否和 nil 相等來判斷可選類型是否有值,如下:
if surveyAnswer != nil {
????print("surveyAnswer has a value.")
}
當(dāng)確定可選類型一定有值時(shí),可以在可選類型的名字后面加一個(gè)感嘆號(hào)(!)來獲取值,這個(gè)感嘆號(hào)表示“我知道這個(gè)可選有值,請(qǐng)使用它。如下:
surveyAnswer ="一定有值"
if surveyAnswer != nil {
????print(surveyAnswer!)//使用 !進(jìn)行強(qiáng)制解析
} else{
????print("值為nil")
}
注意:強(qiáng)制解包是一種危險(xiǎn)的行為,一旦解包失敗,就有可能崩潰。
可選綁定(optional binding)
使用可選綁定來判斷可選類型是否有值,如果包含就把值賦給一個(gè)臨時(shí)的變量或常量??蛇x綁定可以用在 if 和 while 語(yǔ)句中,這條語(yǔ)句不僅可以用來判斷可選類型是否有值,同時(shí)可以將可選類型的值賦給一個(gè)常量或者變量。
下面看下如何在 if 語(yǔ)句中使用可選綁定:
if actualAnswer = surveyAnswer {
????print(surveyAnswer)//不需要使用 !進(jìn)行強(qiáng)制解析
} else {
????print("值為nil")
}
類似的,我們還可以使用 guard let 的方式來進(jìn)行解包,如下:
guard let actualAnswer = surveyAnswerelse {
????print("值為nil")
}
print(surveyAnswer) //不需要使用 !進(jìn)行強(qiáng)制解析
在 guard let 中,else 中的大括號(hào)是異常情況。而外部主體是正常的情況。
還可以在一個(gè) if 語(yǔ)句中包含多個(gè)可選綁定或布爾條件,中間用逗號(hào)分割。只要任意一個(gè)可選綁定的值為 nil ,或者任意布爾條件為 false,則整個(gè) if 條件為 false,下面兩個(gè)語(yǔ)句是等價(jià)的:
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber <100 {
????print("\(firstNumber)<\(secondNumber)< 100")
}// Prints "4 < 42 < 100"
if let firstNumber = Int("4") {
????if letsecondNumber = Int("42")? {
????????if firstNumber < secondNumber && secondNumber <100 {
????????????print("\(firstNumber)<\(secondNumber)< 100")? ? ?
?????????}? ??
????}
}
隱式解析可選類型
我們已經(jīng)知道,可選類型聲明的變量或常量可能有值,也有可能沒有值,我們需要通過解析來使用可選類型的值。然而,如果我們?cè)谝婚_始就已經(jīng)確定這個(gè)可選類型一定有值,如果每次都判斷和解析可選類型是非常低效的,這樣,隱式解析可選類型就出現(xiàn)了。
隱式解析可選類型是可選類型的一種,但是可以被當(dāng)做非可選類型來使用,并不需要每次都使用解析來獲取可選值。它們之間唯一的區(qū)別是,隱式解析可選類型是對(duì)?Swift?編譯器的一個(gè)承諾,即在運(yùn)行時(shí)訪問時(shí),它的值不會(huì)為?nil。
通過將可選的類型的后面的問號(hào)(String?)改成感嘆號(hào)(String!)來聲明一個(gè)隱式解析可選類型。
通過下面例子看一下,可選類型 String 和隱式解析可選類型 String 之間的區(qū)別:
let possibleString:String? = "An optional string."
letforcedString:String= possibleString!// 需要感嘆號(hào)來獲取值
letassumedString:String! ="An implicitly unwrapped optional string."
letimplicitString:String= assumedString // 不需要感嘆號(hào)
注意:如果你在隱式解析可選類型沒有值的時(shí)候嘗試取值,會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤。