美文网首页iOS 开发每天分享优质文章
Swift 源码解读 - Optional.swift

Swift 源码解读 - Optional.swift

作者: YxxxHao | 来源:发表于2018-03-26 22:42 被阅读160次

    Optional 作为 Swift 中最重要的语言特性之一,下面来解读下 Optional 的源码。

    Optional 在 Swift 中是一个包含 none 和 some 两个 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,我们可以通过代码来验证一下:

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

    如果存在一个值使用 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 类型进行 map 方法里,如果值为 none 时, 直接返回 nil,如果为 some(Wrapped) 时,返回 some(transform(Wrapped)),可以通过以下代码来验证:

    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 时,直接我返回 nil,如果不为 nil 时,some 进行解包并 transform。需要注意的是,transform 时是解包值,但 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)
    

    关于更多 map 和 flatMap 内容,可以参看 Swift 源码解读 - Map.swift 一文

    unsafelyUnwrapped

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

    unsafelyUnwrapped 和 强制解包符 ! 的功能是相似的,如果为 nil 时执行,则会报错:

    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 文件里面还有一些 == 、 != 、?? 等方法的实现,以及和 OC 桥接的内容,这里就不一一讲解,有兴趣可以自己研究下。

    扩展 - Optional 常用方法

    1. ! 强制解包符 // 如果为 nil 时, 运行时会出错
    2. if let x = x {}
    3. guard let x = x else { return } // 推荐用法

    相关文章

      网友评论

        本文标题:Swift 源码解读 - Optional.swift

        本文链接:https://www.haomeiwen.com/subject/awudcftx.html