swift - optional 可選值

Swift 中的可選類型(Optional)是一種特殊的數(shù)據(jù)類型悯恍,用于表示一個(gè)值可能存在,也可能不存在伙狐′毯粒可選類型是一種安全機(jī)制,用于避免在變量的值為 nil(不存在)時(shí)引用或操作該值贷屎,從而減少運(yùn)行時(shí)錯(cuò)誤罢防。通過可選類型,Swift 在編譯時(shí)就可以檢查到潛在的空值錯(cuò)誤唉侄。

定義可選類型

要將任何類型定義為可選類型咒吐,請(qǐng)?jiān)陬愋秃竺嫣砑訂柼?hào)(?)。例如属划,定義一個(gè) String 類型的可選類型:

var optionalName: String?

此時(shí)恬叹,這個(gè)變量的值可以是一個(gè)字符串,也可以是 nil同眯。默認(rèn)情況下绽昼,可選類型的初始值為 nil

解包(Unwrapping)

訪問可選類型的值時(shí)嗽测,需要解包(Unwrapping)操作绪励。解包是從可選類型中取出實(shí)際的值(如果存在的話)的過程。有兩種常用的解包方法:

  1. 強(qiáng)制解包(Forced Unwrapping):在變量后面添加感嘆號(hào)(!)來強(qiáng)制解包唠粥。這種方法要求在解包時(shí)疏魏,變量一定不是 nil,否則會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤晤愧。強(qiáng)制解包存在風(fēng)險(xiǎn)大莫,不建議在實(shí)際編程中使用。

    示例如下:

    let optionalNumber: Int? = 5
    let unwrappedNumber = optionalNumber! // 強(qiáng)制解包官份,得到整數(shù)類型的值
    print(unwrappedNumber) // 輸出: 5
    
  2. 可選綁定(Optional Binding):使用 if letguard let 語句進(jìn)行可選綁定只厘。這種方法更為安全,因?yàn)樵诮獍^程中舅巷,代碼可確保變量不是 nil羔味。

    示例如下:

    let optionalNumber: Int? = 5
    
    if let unwrappedNumber = optionalNumber {
        print(unwrappedNumber) // 輸出: 5
    } else {
        print("The number is nil.")
    }
    
    func printFullName(firstName: String?, lastName: String?) {
        guard let firstNameValue = firstName else {
            print("First name is nil.")
            return
        }
        
        
        guard let lastNameValue = lastName else {
            print("Last name is nil.")
            return
        }
        
        print("Full name: \(firstNameValue) \(lastNameValue)")
    }
    
    printFullName(firstName: "John", lastName: "Doe") // 輸出: "Full name: John Doe"
    printFullName(firstName: nil, lastName: "Doe") // 輸出: "First name is nil."
    printFullName(firstName: "John", lastName: nil) // 輸出: "Last name is nil."
    

可選鏈(Optional Chaining)

可選鏈?zhǔn)且环N可以請(qǐng)求并調(diào)用可選類型屬性、方法或下標(biāo)的過程钠右。如果可選類型包含值赋元,調(diào)用會(huì)成功;如果可選類型為 nil,調(diào)用會(huì)返回 nil搁凸,不會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤媚值。可選鏈的返回值始終是可選類型护糖。

示例如下:

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let person = Person()

if let roomCount = person.residence?.numberOfRooms {
    print("Number of rooms: \(roomCount)")
} else {
    print("Unable to retrieve the number of rooms.")
}

在這個(gè)示例中褥芒,person.residence 的類型為 Residence?(可選類型)。通過可選鏈嫡良,我們嘗試調(diào)用 numberOfRooms 屬性锰扶,而不需要手動(dòng)解包。如果 person.residencenil皆刺,調(diào)用將安全地返回 nil少辣,而不會(huì)觸發(fā)錯(cuò)誤。

在實(shí)際編程中羡蛾,可能需要處理各種場景,其中變量的值可能存在锨亏,也可能不存在痴怨。使用可選類型可以確保這些操作能在編譯過程中有安全性檢查,從而避免運(yùn)行時(shí)錯(cuò)誤器予。在 Swift 中浪藻,可選類型是一種重要的機(jī)制,減少了潛在的 nil 引用錯(cuò)誤乾翔。

可選值的底層實(shí)現(xiàn)

Swift 中的可選類型(Optional)在底層是通過枚舉實(shí)現(xiàn)的爱葵。Optional 枚舉有兩個(gè)成員:nonesomenone 表示沒有值(類似于其他語言的 nullnil)反浓,some 表示一個(gè)包裝的值萌丈。Optional 枚舉包含一個(gè)泛型參數(shù),為實(shí)際值的類型雷则。

以下是 Optional 枚舉的簡化定義:

enum Optional<Wrapped> {
    case none
    case some(Wrapped)
}

在這里辆雾,泛型參數(shù) Wrapped 表示待包裝的實(shí)際值。當(dāng)一個(gè) Optional 類型存在實(shí)際值時(shí)月劈,枚舉將實(shí)際值存儲(chǔ)在 some 成員中度迂;當(dāng) Optional 類型為 nil 時(shí),它使用 none 成員猜揪。這種枚舉形式允許 Swift 在編譯時(shí)檢查潛在的 nil 值和實(shí)際值的使用惭墓。

下面我們使用 Optional 枚舉的顯式定義來創(chuàng)建一個(gè)可選整數(shù):

let optionalNumber: Optional<Int> = .some(5)

這是通過簡寫創(chuàng)建相同可選整數(shù)的方式:

let optionalNumber: Int? = 5

在可選類型的解包過程中,編譯器將會(huì)根據(jù)枚舉成員進(jìn)行判斷而姐。例如腊凶,使用可選綁定時(shí),編譯器會(huì)檢查底層的枚舉是否為 some 成員,如果是吭狡,將實(shí)際值解包尖殃。否則,編譯器將知道值為 none划煮,不會(huì)執(zhí)行相應(yīng)的代碼塊送丰。

以下是可選綁定的底層原理:

let optionalNumber: Optional<Int> = .some(5)

switch optionalNumber {
case .some(let value):
    print("Unwrapped value: \(value)")
case .none:
    print("The value is nil.")
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市弛秋,隨后出現(xiàn)的幾起案子器躏,更是在濱河造成了極大的恐慌,老刑警劉巖蟹略,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件登失,死亡現(xiàn)場離奇詭異,居然都是意外死亡挖炬,警方通過查閱死者的電腦和手機(jī)揽浙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來意敛,“玉大人馅巷,你說我怎么就攤上這事〔菀觯” “怎么了钓猬?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撩独。 經(jīng)常有香客問我敞曹,道長,這世上最難降的妖魔是什么综膀? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任澳迫,我火速辦了婚禮,結(jié)果婚禮上僧须,老公的妹妹穿的比我還像新娘纲刀。我一直安慰自己,他們只是感情好担平,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布示绊。 她就那樣靜靜地躺著,像睡著了一般暂论。 火紅的嫁衣襯著肌膚如雪面褐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天取胎,我揣著相機(jī)與錄音展哭,去河邊找鬼湃窍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛匪傍,可吹牛的內(nèi)容都是我干的您市。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼役衡,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼茵休!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起手蝎,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤榕莺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后棵介,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钉鸯,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年邮辽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唠雕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逆巍,死狀恐怖及塘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锐极,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布芳肌,位于F島的核電站灵再,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏亿笤。R本人自食惡果不足惜翎迁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望净薛。 院中可真熱鬧汪榔,春花似錦、人聲如沸肃拜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽燃领。三九已至士聪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猛蔽,已是汗流浹背剥悟。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工灵寺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人区岗。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓略板,卻偏偏與公主長得像,于是被迫代替她去往敵國和親慈缔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子叮称,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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