** if 語句以及強(qiáng)制解析**
你可以使用 if 語句和 nil 比較來判斷一個(gè)可選值是否包含值。你可以使用“相等”(==)或“不等”( != )來執(zhí)行比較辟狈。
如果可選類型有值,它將不等于 nil:
<pre>if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
// 輸出 "convertedNumber contains some integer value."</pre>
當(dāng)你確定可選類型確實(shí)包含值之后逐纬,你可以在可選的名字后面加一個(gè)感嘆號(hào)( ! )來獲取值逝段。這個(gè)驚嘆
號(hào)表示“我知道這個(gè)可選有值刷允,請(qǐng)使用它《髦溃”這被稱為可選值的強(qiáng)制解析(forced unwrapping):
<pre>if convertedNumber != nil {
print("convertedNumber has an integer value of (convertedNumber!).")
}
// 輸出 "convertedNumber has an integer value of 123."</pre>
注意:使用 ! 來獲取一個(gè)不存在的可選值會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤倡鲸。使用 ! 來強(qiáng)制解析值之前,一定要確定可選包
含一 個(gè)非 nil 的值黄娘。
可選綁定
使用可選綁定(optional binding)來判斷可選類型是否包含值峭状,如果包含就把值賦給一個(gè)臨時(shí)常量
或者變量〈绾辏可選綁定可以用在 if 和 while 語句中宁炫,這條語句不僅可以用來判斷可選類型中是否有
值,同時(shí)可以將可選類型中的值賦給一個(gè)常量或者變量氮凝。
if 和 while 語句像下面這樣在 if 語句中寫一個(gè)可選綁定:
<pre>if let constantName = someOptional {
statements
}</pre>
你可以像上面這樣使用可選綁定來重寫 possibleNumber
<pre>if let actualNumber = Int (possibleNumber) {
print("'(possibleNumber)' has an integer value of (actualNumber)")
} else {
print("'(possibleNumber)' could not be converted to an integer")
}
// 輸出 "'123' has an integer value of 123"</pre>
這段代碼可以被理解為:
“如果 Int(possibleNumber) 返回的可選 Int 包含一個(gè)值羔巢,創(chuàng)建一個(gè)叫做 actualNumber 的
新常量并將可選包含的值賦給它。”如果轉(zhuǎn)換成功竿秆, actualNumber 常量可以在 if 語句的第一個(gè)分支中使用启摄。它已經(jīng)被可選類型包含的值初始化過,所以不需要再使用 ! 后綴來獲取它的值幽钢。在這個(gè)例子中歉备,actualNumber 只被用來輸出轉(zhuǎn)換結(jié)果。
你可以在可選綁定中使用常量和變量匪燕。如果你想在if語句的第一個(gè)分支中操作 actualNumber 的值蕾羊,
你可以改 成 if var actualNumber ,這樣可選類型包含的值就會(huì)被賦給一個(gè)變量而非常量帽驯。
你可以包含多個(gè)可選綁定或多個(gè)布爾條件在一個(gè) if 語句中龟再,只要使用逗號(hào)分開就行。只要有任意一個(gè)
可選綁定的值為nil尼变,或者任意一個(gè)布爾條件為false利凑,則整個(gè)if條件判斷為false,這時(shí)你就需要使
用嵌套 if 條件語句來處理嫌术,如下所示:
<pre>if let firstNumber = Int("4"), let secondNumber = Int("42"),
firstNumber < secondNumber && secondNumber < 100
{
print("(firstNumber) < (secondNumber) < 100")
}
// 輸出 "4 < 42 < 100"
if let firstNumber = Int("4") {
if let secondNumber = Int("42") {
if firstNumber < secondNumber && secondNumber < 100{
print("(firstNumber) < (secondNumber) < 100")
}
}
}
// 輸出 "4 < 42 < 100"</pre>
注意: 在 if 條件語句中使用常量和變量來創(chuàng)建一個(gè)可選綁定哀澈,僅在 if 語句的句中( body )中才
能獲取到值。
相反度气,在 guard 語句中使用常量和變量來創(chuàng)建一個(gè)可選綁定割按,僅在 guard 語句外且在語句后才能獲
取到值
隱式解析可選類型
如上所述,可選類型暗示了常量或者變量可以“沒有值”蚯嫌≌芟海可選可以通過 if 語句來判斷是否有值,如果
有值的話可以通過可選綁定來解析值择示。
有時(shí)候在程序架構(gòu)中束凑,第一次被賦值之后,可以確定一個(gè)可選類型總會(huì)有值栅盲。在這種情況下汪诉,每次都判
斷和解析可選值是非常低效的,因?yàn)榭梢源_定它總會(huì)有值谈秫。
這種類型的可選狀態(tài)被定義為隱式解析可選類型(implicitly unwrapped optionals)扒寄。把想要用
作可選的類型的后面的問號(hào)( String? )改成感嘆號(hào)( String! )來聲明一個(gè)隱式解析可選類型。
當(dāng)可選類型被第一次賦值之后就可以確定之后一直有值的時(shí)候拟烫,隱式解析可選類型非常有用该编。隱式解析
可選類型主要被用在 Swift 中類的構(gòu)造過程中
一個(gè)隱式解析可選類型其實(shí)就是一個(gè)普通的可選類型,但是可以被當(dāng)做非可選類型來使用硕淑,并不需要每
次都使用解析來獲取可選值课竣。下面的例子展示了可選類型 String 和隱式解析可選類型 String 之間
的區(qū)別:
<pre>let possibleString: String? = "An optional string."http://可選類型
let forcedString: String = possibleString! // 需要感嘆號(hào)來獲取值
let assumedString: String! = "An implicitly unwrapped optional string."http://隱式解析可選類型
let implicitString: String = assumedString // 不需要感嘆號(hào)</pre>
錯(cuò)誤處理
你可以使用 錯(cuò)誤處理(error handling) 來應(yīng)對(duì)程序執(zhí)行中可能會(huì)遇到的錯(cuò)誤條件嘉赎。
相對(duì)于可選中運(yùn)用值的存在與缺失來表達(dá)函數(shù)的成功與失敗,錯(cuò)誤處理可以推斷失敗的原因于樟,并傳播至程序的其他部分公条。
當(dāng)一個(gè)函數(shù)遇到錯(cuò)誤條件,它能報(bào)錯(cuò)迂曲。調(diào)用函數(shù)的地方能拋出錯(cuò)誤消息并合理處理靶橱。
func canThrowAnError() throws {
// 這個(gè)函數(shù)有可能拋出錯(cuò)誤
}
一個(gè)函數(shù)可以通過在聲明中添加關(guān)鍵詞來拋出錯(cuò)誤消息。當(dāng)你的函數(shù)能拋出錯(cuò)誤消息時(shí), 你應(yīng)該在表達(dá)式中前置關(guān)鍵詞路捧。
do {
try canThrowAnError() // 沒有錯(cuò)誤消息拋出
} catch {
// 有一個(gè)錯(cuò)誤消息拋出
}
斷言
可選類型可以讓你判斷值是否存在关霸,你可以在代碼中優(yōu) 地處理值缺失的情況。然而鬓长,在某些情況下谒拴,如果值缺 失或者值并不滿足特定的條件,你的代碼可能
沒辦法繼續(xù)執(zhí)行涉波。這時(shí),你可以在你的代碼中觸發(fā)一個(gè) 斷言(assertion) 來結(jié)束代碼運(yùn)行并通過調(diào)試來找到值缺失的原因炭序。
你可以使用全局 assert(::file:line:) 函數(shù)來寫一個(gè)斷言啤覆。向這個(gè)函數(shù)傳入一個(gè)結(jié)果為 true 或者 false 的表達(dá)式以及一條信息,當(dāng)表達(dá)式的結(jié)果為 false 的時(shí)候這條信息會(huì)被顯示:
<pre>let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// 因?yàn)?age < 0惭聂,所以斷言會(huì)觸發(fā)</pre>
如果不需要斷言信息窗声,可以省略,就像這樣:
assert(age >= 0)
何時(shí)使用斷言
當(dāng)條件可能為假時(shí)使用斷言辜纲,但是最終一定要保證條件為真笨觅,這樣你的代碼才能繼續(xù)運(yùn)行。斷言的適用情景:
? 整數(shù)類型的下標(biāo)索引被傳入一個(gè)自定義下標(biāo)實(shí)現(xiàn)耕腾,但是下標(biāo)索引值可能太小或者太大见剩。
? 需要給函數(shù)傳入一個(gè)值,但是非法的值可能導(dǎo)致函數(shù)不能正常執(zhí)行扫俺。
? 一個(gè)可選值現(xiàn)在是 nil 苍苞,但是后面的代碼運(yùn)行需要一個(gè)非 nil 值。