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 常用方法
- ! 強(qiáng)制解包符 // 如果為 nil 時(shí)畴蒲, 運(yùn)行時(shí)會(huì)出錯(cuò)
- if let x = x {}
- guard let x = x else { return } // 推薦用法