Swift 源碼解讀 - Optional.swift

Optional 作為 Swift 中最重要的語言特性之一,下面來解讀下 Optional 的源碼。

Optional 在 Swift 中是一個(gè)包含 none 和 some 兩個(gè) case 的 enum:

public enum Optional<Wrapped> : ExpressibleByNilLiteral {
  
  /// 代碼中使用 nil 來代替 none 的枚舉
  case none

  /// The presence of a value, stored as `Wrapped`.
  case some(Wrapped)
}

case none 在代碼中用 nil 來代碼回官,即 nil == .none,我們可以通過代碼來驗(yàn)證一下:

print(nil == Optional.none) // true

如果存在一個(gè)值使用 some(Wrapped):

let num: Int? = 1
print(num)    // Optional(1)
switch num {
case .some(let n):
    print(n)  // 1
case .none:
    print("nim is nil")
}

在 Optional 中的 map 方法

  @_inlineable
  public func map<U>(
    _ transform: (Wrapped) throws -> U
  ) rethrows -> U? {
    switch self {
    case .some(let y):
      return .some(try transform(y))
    case .none:
      return .none
    }
  }

Optional 類型進(jìn)行 map 方法里埂蕊,如果值為 none 時(shí)往弓, 直接返回 nil,如果為 some(Wrapped) 時(shí)蓄氧,返回 some(transform(Wrapped))函似,可以通過以下代碼來驗(yàn)證:

let num1: Int? = nil
print (num1.map { $0 * 2 }) // nil

let num2: Int? = 2
print (num2.map { $0 * 2 }) // Optional(4)

在 Optional 中的 flatMap 方法

@_inlineable
  public func flatMap<U>(
    _ transform: (Wrapped) throws -> U?
  ) rethrows -> U? {
    switch self {
    case .some(let y):
      return try transform(y)
    case .none:
      return .none
    }
  }

Optional 中的 flatMap 方法,如果值為 nil 時(shí)喉童,直接我返回 nil撇寞,如果不為 nil 時(shí),some 進(jìn)行解包并 transform堂氯。需要注意的是重抖,transform 時(shí)是解包值,但 return 返回的還是 Optional

let num1: Int? = nil
print (num1.flatMap { $0 * 2 }) // nil

let num2: Int? = 2
num2.flatMap { print($0 * 2) } // 4
print (num2.flatMap { $0 * 2 }) // Optional(4)

關(guān)于更多 map 和 flatMap 內(nèi)容祖灰,可以參看 Swift 源碼解讀 - Map.swift 一文

unsafelyUnwrapped

  @_inlineable
  public var unsafelyUnwrapped: Wrapped {
    @inline(__always)
    get {
      if let x = self {
        return x
      }
      _debugPreconditionFailure("unsafelyUnwrapped of nil optional")
    }
  }

unsafelyUnwrapped 和 強(qiáng)制解包符 ! 的功能是相似的,如果為 nil 時(shí)執(zhí)行畔规,則會(huì)報(bào)錯(cuò):

let num1: Int? = 2
print(num1!)  // 2
print(num1.unsafelyUnwrapped) // 2

let num2: Int? = nil
print(num2!)  // Fatal error: Unexpectedly found nil while unwrapping an Optional value
print(num2.unsafelyUnwrapped) // Fatal error: unsafelyUnwrapped of nil optional

Optional.swift 文件里面還有一些 == 局扶、 != 、?? 等方法的實(shí)現(xiàn)叁扫,以及和 OC 橋接的內(nèi)容三妈,這里就不一一講解,有興趣可以自己研究下莫绣。

擴(kuò)展 - Optional 常用方法

  1. ! 強(qiáng)制解包符 // 如果為 nil 時(shí)畴蒲, 運(yùn)行時(shí)會(huì)出錯(cuò)
  2. if let x = x {}
  3. guard let x = x else { return } // 推薦用法

推薦閱讀
Swift 解讀 - 前言
Swift 解讀 - Collection 大家族(上篇)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市对室,隨后出現(xiàn)的幾起案子模燥,更是在濱河造成了極大的恐慌,老刑警劉巖掩宜,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔫骂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡牺汤,警方通過查閱死者的電腦和手機(jī)辽旋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來檐迟,“玉大人补胚,你說我怎么就攤上這事∽烦伲” “怎么了溶其?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)敦间。 經(jīng)常有香客問我握联,道長(zhǎng)桦沉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任金闽,我火速辦了婚禮纯露,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘代芜。我一直安慰自己埠褪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布挤庇。 她就那樣靜靜地躺著钞速,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嫡秕。 梳的紋絲不亂的頭發(fā)上渴语,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音昆咽,去河邊找鬼驾凶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛掷酗,可吹牛的內(nèi)容都是我干的调违。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼泻轰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼技肩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起浮声,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤虚婿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后泳挥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雳锋,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年羡洁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玷过。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筑煮,死狀恐怖辛蚊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情真仲,我是刑警寧澤袋马,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站秸应,受9級(jí)特大地震影響虑凛,放射性物質(zhì)發(fā)生泄漏碑宴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一桑谍、第九天 我趴在偏房一處隱蔽的房頂上張望延柠。 院中可真熱鬧,春花似錦锣披、人聲如沸贞间。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)增热。三九已至,卻和暖如春胧辽,著一層夾襖步出監(jiān)牢的瞬間峻仇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工邑商, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摄咆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓奠骄,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親番刊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子含鳞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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

  • 昨天去冒了個(gè)險(xiǎn),寫作是我的鎧甲芹务。 事情是這樣的: 我們機(jī)構(gòu)入選了2017年第三屆群島教育加速器蝉绷,接受一年的創(chuàng)業(yè)孵化...
    山間竹音閱讀 270評(píng)論 0 1
  • Charles??的情書。愛枣抱,是被激情點(diǎn)燃對(duì)酒精熔吗;愛愛,是從心底流淌的歌;愛佳晶,是兩個(gè)孤獨(dú)靈魂的對(duì)話桅狠;愛,是漫漫人生...
    courtlike閱讀 136評(píng)論 0 0
  • 糖寶明白聊天是什么挺久了轿秧,經(jīng)常晚上睡覺時(shí)要求媽媽“我們聊聊天吧”中跌。我也有意識(shí)引導(dǎo)孩子回憶當(dāng)天發(fā)生的事情 今天一躺下...
    瑋瑋笨笨閱讀 172評(píng)論 0 0
  • by 覆舟 柳眉寒黛,顰笑煙波沒菇篡。悵佳期何許漩符,清秋落。思錦瑟華年驱还,風(fēng)也得嗜暴,雨也過凸克。而今空回首,歲月如歌闷沥,唱盡人生愁...
    陳覆舟閱讀 231評(píng)論 1 6
  • 1.安裝git 2.創(chuàng)建本地倉(cāng)庫(kù) 3.初始化本地倉(cāng)庫(kù): 4.添加遠(yuǎn)程倉(cāng)庫(kù)origin是遠(yuǎn)程庫(kù)的默認(rèn)名稱萎战,通過htt...
    薛云龍閱讀 525評(píng)論 0 0