Swift-可選類型

在值可能不存在的情況下,您可以使用可選值栗弟。 可選表示兩種可能性:有一個值,您可以解開可選值以訪問該值工闺,或者根本沒有值乍赫。
這里有一個例子說明如何使用可選項來處理缺少值。 Swift的Int類型有一個初始化器陆蟆,它試圖將String值轉(zhuǎn)換為Int值雷厂。 但是,不是每個字符串都可以轉(zhuǎn)換為整數(shù)叠殷。 字符串“123”可以轉(zhuǎn)換為數(shù)字值123改鲫,但是字符串“hello,world”沒有一個明顯的數(shù)值要轉(zhuǎn)換林束。

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber is inferred to be of type "Int?", or "optional Int"

因為初始化程序可能失敗像棘,它返回一個可選的Int,而不是一個Int壶冒。 可選的Int被寫為Int ?,而不是Int缕题。 問號表示它包含的值是可選的,這意味著它可能包含一些Int值胖腾,或者它可能不包含任何值避除。 (它不能包含任何其他的,如Bool值或String值胸嘁,它是一個Int,或者它根本不是凉逛。
您通過為可選變量賦值特殊值nil將其設(shè)置為無價值狀態(tài):

var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value

nil不能與非可選常量和變量一起使用性宏。 如果代碼中的常量或變量需要在某些條件下缺少某個值,請將其聲明為適當(dāng)類型的可選值状飞。
如果您定義一個可選變量而不提供默認(rèn)值毫胜,則變量將自動設(shè)置為nil:

var surveyAnswer: String?
// surveyAnswer is automatically set to nil

注意:Swift的nil與Objective-C中的nil不一樣。 在Objective-C中诬辈,nil是一個指向不存在的對象的指針酵使。 在Swift中,nil不是一個指針 - 它是一個類型的值的缺失焙糟。 任何類型的可選項都可以設(shè)置為nil口渔,而不僅僅是對象類型。

if語句和強(qiáng)制解包

您可以使用if語句通過將可選項與nil進(jìn)行比較來確定可選項是否包含值穿撮。 您可以使用“等于”運(yùn)算符(==)或“不等于”運(yùn)算符(缺脉!=)執(zhí)行此比較痪欲。
如果一個可選項有一個值,它被認(rèn)為是“不等于”nil:

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
}
// Prints "convertedNumber contains some integer value."

一旦確定可選項包含一個值攻礼,就可以通過在可選項名稱的末尾添加一個感嘆號(R堤摺)來訪問其底層值。 這被稱為強(qiáng)制解開可選值的值(強(qiáng)制解包):

if convertedNumber != nil {
print("convertedNumber has an integer value of \(convertedNumber!).")
}
// Prints "convertedNumber has an integer value of 123."

可選綁定

您可以使用可選綁定來確定一個可選的是否包含一個值礁扮,如果包含知举,則使該值作為臨時常量或變量。 可選綁定可以與if和while語句一起使用太伊,以檢查可選內(nèi)部中的值雇锡,并將該值提取為常量或變量,作為單個操作的一部分倦畅。
為if語句編寫可選綁定遮糖,如下所示:

let possibleNumber = "123"
if let actualNumber = Int(possibleNumber) {
    print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
    print("\"\(possibleNumber)\" could not be converted to an integer")
}
// Prints ""123" has an integer value of 123"
這段代碼的意思是:“如果Int(possibleNumber)返回的可選Int包含一個值,請將一個名為actualNumber的新常量設(shè)置為可選值中包含的值叠赐。
  • 如果轉(zhuǎn)換成功欲账,actualNumber常量可以在if語句的第一個分支中使用。 它已經(jīng)被包含在可選內(nèi)容中的值初始化芭概,因此沒有必要使用赛不! 后綴來訪問它的值。 在此示例中罢洲,actualNumber僅用于打印轉(zhuǎn)換的結(jié)果踢故。
  • 您可以使用常量和變量與可選綁定。 如果你想在if語句的第一個分支中操作actualNumber的值惹苗,你可以改寫var actualNumber殿较,并且可選內(nèi)容中包含的值將作為變量而不是常量。

您可以根據(jù)需要在單個if語句中包含盡可能多的可選綁定和布爾條件桩蓉,并以逗號分隔淋纲。 如果可選綁定中的任何值為nil或任何布爾條件求值為false,則整個if語句的條件被視為false院究。 以下if語句是等效的:

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 let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
        }
    }
}
// Prints "4 < 42 < 100"

在if語句中使用可選綁定創(chuàng)建的常量和變量僅在if語句的主體中可用洽瞬。 相反,用guard語句創(chuàng)建的常量和變量在保護(hù)語句之后的代碼行中可用业汰。

隱式解包

  • 如上所述伙窃,可選項指示允許常數(shù)或變量具有“nil”。 可選項可以使用if語句檢查以查看值是否存在样漆,并且可以使用可選綁定有條件地解開为障,以訪問可選值(如果存在)。
  • 有時,從程序的結(jié)構(gòu)中可以清楚地看出产场,可選項將始終具有值鹅髓,在該值首次設(shè)置之后。 在這些情況下京景,刪除每次訪問可選值時都需要檢查和解開可選值窿冯,這是非常有用的,因為它可以安全地假定所有時間都有一個值确徙。
  • 這些類型的可選項被定義為隱式解包的可選項醒串。 通過在要使其可選的類型之后放置感嘆號(String!)而不是問號(String鄙皇?)來編寫隱式解包的可選屬性芜赌。
  • 當(dāng)Swift中隱式解包的可選屬性的主要用途是在類初始化期間。

隱式解包的可選是后臺的正嘲橐荩可選缠沈,但也可以像非可選值一樣使用,而不需要在每次訪問時解包可選值错蝴。 以下示例顯示了在將其包裝值作為顯式字符串訪問時洲愤,可選字符串和隱式未包裝可選字符串之間的行為差異:

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

您可以將隱式展開的可選項視為授予可選項在使用時自動展開的權(quán)限。 在每次使用可選名稱后顷锰,不要在可選名稱后面放置感嘆號柬赐,而是在聲明后在可選類型之后放置感嘆號。
注意:如果隱式解包的可選項為nil官紫,并且嘗試訪問其包裝值肛宋,則會觸發(fā)運(yùn)行時錯誤。 結(jié)果與在不包含值的正呈溃可選參數(shù)之后放置感嘆號完全相同酝陈。
您仍然可以將一個隱式解開的可選項(如普通可選項)視為是否包含值:

if assumedString != nil {
    print(assumedString)
}
// Prints "An implicitly unwrapped optional string."

您還可以使用帶有可選綁定的隱式解包可選,以在單個語句中檢查和解包其值:

if let definiteString = assumedString {//如果隱式解包中的無值(nil)則視為解包失敗毁涉,如果有值沉帮,就把這個作為一個新值,去創(chuàng)建一個名為‘definiteString’的常量薪丁,這個常量在if的語句體內(nèi)可用。
    print(definiteString)
}
// Prints "An implicitly unwrapped optional string."

注意:當(dāng)變量有可能在程序中變?yōu)閚il時馅精,不要使用隱式解包严嗜。 如果需要在變量的生命周期中檢查有沒有值,請始終使用正常的可選類型(在變量聲明的時候加洲敢?)漫玄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子睦优,更是在濱河造成了極大的恐慌渗常,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汗盘,死亡現(xiàn)場離奇詭異皱碘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)隐孽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門癌椿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人菱阵,你說我怎么就攤上這事踢俄。” “怎么了晴及?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵都办,是天一觀的道長。 經(jīng)常有香客問我虑稼,道長琳钉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任动雹,我火速辦了婚禮槽卫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胰蝠。我一直安慰自己歼培,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布茸塞。 她就那樣靜靜地躺著躲庄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钾虐。 梳的紋絲不亂的頭發(fā)上噪窘,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音效扫,去河邊找鬼倔监。 笑死,一個胖子當(dāng)著我的面吹牛菌仁,可吹牛的內(nèi)容都是我干的浩习。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼济丘,長吁一口氣:“原來是場噩夢啊……” “哼谱秽!你這毒婦竟也來了洽蛀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤疟赊,失蹤者是張志新(化名)和其女友劉穎郊供,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體近哟,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驮审,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了椅挣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片头岔。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鼠证,靈堂內(nèi)的尸體忽然破棺而出峡竣,到底是詐尸還是另有隱情,我是刑警寧澤量九,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布适掰,位于F島的核電站,受9級特大地震影響荠列,放射性物質(zhì)發(fā)生泄漏类浪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一肌似、第九天 我趴在偏房一處隱蔽的房頂上張望费就。 院中可真熱鬧,春花似錦川队、人聲如沸力细。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽眠蚂。三九已至,卻和暖如春斗躏,著一層夾襖步出監(jiān)牢的瞬間逝慧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工啄糙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笛臣,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓隧饼,卻偏偏與公主長得像沈堡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子桑李,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容