656,Objective-C 轉(zhuǎn) Swift 的第一道坎——論如何正確的處理可選類型(重點(diǎn):在Oc中如何表達(dá)swift的基本數(shù)據(jù)類型的可選值衡未,用OC中的NSNotFound)

從 Objective-C 轉(zhuǎn) Swift 開發(fā)已經(jīng)有一段時(shí)間了,這兩門語言在整體的理念上差異還是蠻大的峰伙。在這之中,可選類型的處理是每一個(gè)使用 Swift 的開發(fā)者每天都要面臨的問題音同,理解并正確處理好可選類型對(duì)于寫出高質(zhì)量的 Swift 代碼和保證 iOS 項(xiàng)目的健壯性都是至關(guān)重要的词爬。

可選類型

要想處理好可選類型,就要先理解可選類型权均。

一個(gè)可選類型代表有兩種可能性:有一個(gè)值顿膨,你可以解包可選類型來訪問該值锅锨;或者根本沒有值。

在 Objective-C 中不存在可選類型的概念恋沃,Objective-C 中最接近的東西就是 nil, nil 的意思是“沒有有效的對(duì)象”必搞。但是,這只適用于對(duì)象——它不適用于結(jié)構(gòu)囊咏、基本數(shù)據(jù)類型或枚舉值恕洲。對(duì)于這些類型,Objective-C 方法通常會(huì)返回一個(gè)特殊值(如 NSNotFound)來指示缺少值梅割。這種方法假設(shè)方法的調(diào)用者知道有一個(gè)特殊的值來測(cè)試霜第,并記得檢查它。Swift 的可選值可以讓你指出可能為 nil 的任何類型的值户辞,而不需要特殊的常量泌类。

例如,Swift 的 Int 類型有一個(gè)初始化方法底燎,它試圖將一個(gè) String 值轉(zhuǎn)換成一個(gè) Int 值刃榨。但是,并不是每個(gè)字符串都可以轉(zhuǎn)換成一個(gè)整數(shù)双仍。字符串 "123" 可以轉(zhuǎn)換為數(shù)字值 123枢希,但字符串 "Hello, world" 沒有一個(gè)明顯的數(shù)值要轉(zhuǎn)換。

下面的例子使用初始化方法來嘗試將一個(gè)字符串轉(zhuǎn)換為一個(gè) Int:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推斷為 "Int?" 類型或 “可選的 Int”

nil

通過賦值給它一個(gè)特殊的值 nil 來設(shè)置一個(gè)可選變量為無值狀態(tài):

var serverResponseCode: Int? = 404
// serverResponseCode 包含一個(gè)實(shí)際的 Int 值為 404
serverResponseCode = nil
// serverResponseCode 現(xiàn)在不包含任何值 

如果你定義了一個(gè)可選變量而不提供默認(rèn)值朱沃,則該變量會(huì)自動(dòng)設(shè)置為 nil:

var surveyAnswer: String?
// surveyAnswer 自動(dòng)設(shè)置為 nil

Swift 的 nil 與 Objective-C 中的 nil 不相同苞轿。在 Objective-C 中,nil 是一個(gè)指向不存在對(duì)象的指針逗物。在 Swift 中呕屎,nil 不是一個(gè)指針,它是缺少某種類型的值敬察。任何類型的可選值都可以被設(shè)置為 nil秀睛,而不僅僅是對(duì)象類型。

可選綁定

你可以使用可選綁定來發(fā)現(xiàn)可選值是否包含值莲祸,如果有蹂安,則使用該值用作臨時(shí)常量或變量∪裰模可選綁定可以與 if 和 while 語句一起使用田盈,以檢查可選值內(nèi)部的值,并將該值提取為常量或變量缴阎,作為單次操作的一部分允瞧。

使用 if 語句編寫一個(gè)可選綁定,如下所示:

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"

如果轉(zhuǎn)換成功,那么 actualNumber 常量可以在 if 語句的第一個(gè)分支中使用述暂。它已經(jīng)被初始化為包含在非可選的值中痹升,所以沒有必要使用 ! 后綴來訪問它的值。

你可以使用可選綁定的常量和變量畦韭。如果你想在 if 語句的第一個(gè)分支內(nèi)操作 actualNumber 的值疼蛾,你可以寫 if var actualNumber,使得可選值作為一個(gè)變量而非常量艺配。

你可以根據(jù)需要在單個(gè) if 語句中包含盡可能多的可選綁定和布爾條件察郁,并用逗號(hào)分隔。如果可選綁定中的任何值為 nil转唉,或者任何布爾條件的計(jì)算結(jié)果為 false皮钠,則整個(gè) if 語句的條件被認(rèn)為是錯(cuò)誤的。以下 if 語句是等價(jià)的:

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"

隱式解包可選類型

有時(shí)從程序的結(jié)構(gòu)中可以清楚的看到赠法,在第一次設(shè)置值之后鳞芙,可選值將始終有一個(gè)值。在這些情況下期虾,每次訪問時(shí)都不需要檢查和解包可選值,因?yàn)榭梢园踩丶俣ㄋ械臅r(shí)間都有一個(gè)值驯嘱。

這些可選值被定義為隱式解包可選值镶苞。你寫一個(gè)隱式解包的可選值,在你想要的可選類型之后放置一個(gè)感嘆號(hào)(String!)而不是一個(gè)問號(hào)(String?)

隱式解包可選值的背后是普通可選值鞠评,但也可以像非可選值一樣使用茂蚓,而不必在每次訪問時(shí)解包可選值。

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 需要感嘆號(hào)
 
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // 不需要感嘆號(hào)

如果隱式解包可選值為 nil剃幌,并且你嘗試訪問其包裝的值聋涨,則會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤。

你仍然可以對(duì)隱式解包可選值使用強(qiáng)制解包和可選綁定负乡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末牍白,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抖棘,更是在濱河造成了極大的恐慌茂腥,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件切省,死亡現(xiàn)場(chǎng)離奇詭異最岗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)朝捆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門般渡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事驯用×郴啵” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵晨汹,是天一觀的道長豹储。 經(jīng)常有香客問我,道長淘这,這世上最難降的妖魔是什么剥扣? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮铝穷,結(jié)果婚禮上钠怯,老公的妹妹穿的比我還像新娘。我一直安慰自己曙聂,他們只是感情好晦炊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宁脊,像睡著了一般断国。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上榆苞,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天稳衬,我揣著相機(jī)與錄音,去河邊找鬼坐漏。 笑死薄疚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赊琳。 我是一名探鬼主播街夭,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼躏筏!你這毒婦竟也來了板丽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤趁尼,失蹤者是張志新(化名)和其女友劉穎檐什,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弱卡,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乃正,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了婶博。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓮具。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出名党,到底是詐尸還是另有隱情叹阔,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布传睹,位于F島的核電站耳幢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏欧啤。R本人自食惡果不足惜睛藻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邢隧。 院中可真熱鬧店印,春花似錦、人聲如沸倒慧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纫谅。三九已至炫贤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間付秕,已是汗流浹背兰珍。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盹牧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓励幼,卻偏偏與公主長得像汰寓,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子苹粟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345