Swift學習:標準庫源碼解析

Swift源碼簡介

  • Swift於2015年正式開源,github地址: https://github.com/apple/swift
  • 幾個可能會經常看的目錄 
  1. docs:一些文檔
  2. stdlib:Swift源碼
  3. lib:C++源碼
  4. include:C++頭文件
  • 標準庫源碼位置
  • https://github.com/apple/swift/tree/master/stdlib/public/core

Array分析

  • map、filter
  •  https://github.com/apple/swift/blob/master/stdlib/public/core/Sequence.swift

map底層源碼:

  public func map<T>(
    _ transform: (Element) throws -> T
  ) rethrows -> [T] {
    let initialCapacity = underestimatedCount
    var result = ContiguousArray<T>()
    result.reserveCapacity(initialCapacity)

    var iterator = self.makeIterator()

    // Add elements up to the initial capacity without checking for regrowth.
    for _ in 0..<initialCapacity {
      result.append(try transform(iterator.next()!))
    }
    // Add remaining elements, if any.
    while let element = iterator.next() {
      result.append(try transform(element))
    }
    return Array(result)
  }

filter底層源碼:

@inlinable
  public __consuming func filter(
    _ isIncluded: (Element) throws -> Bool
  ) rethrows -> [Element] {
    return try _filter(isIncluded)
  }

  @_transparent
  public func _filter(
    _ isIncluded: (Element) throws -> Bool
  ) rethrows -> [Element] {

    var result = ContiguousArray<Element>()

    var iterator = self.makeIterator()

    while let element = iterator.next() {
      if try isIncluded(element) {
        result.append(element)
      }
    }

    return Array(result)
  }

 

  • flatMap、compactMap、reduce
  • https://github.com/apple/swift/blob/master/stdlib/public/core/SequenceAlgorithms.swift

flatMap底層源碼:

 @inlinable
  public func flatMap<SegmentOfResult: Sequence>(
    _ transform: (Element) throws -> SegmentOfResult
  ) rethrows -> [SegmentOfResult.Element] {
    var result: [SegmentOfResult.Element] = []
    for element in self {
      result.append(contentsOf: try transform(element))
    }
    return result
  }
}

reduce底層源碼:


  public func reduce<Result>(
    into initialResult: __owned Result,
    _ updateAccumulatingResult:
      (_ partialResult: inout Result, Element) throws -> ()
  ) rethrows -> Result {
    var accumulator = initialResult
    for element in self {
      try updateAccumulatingResult(&accumulator, element)
    }
    return accumulator
  }
}

compactMap源碼:

 @inlinable // protocol-only
  @inline(__always)
  public func _compactMap<ElementOfResult>(
    _ transform: (Element) throws -> ElementOfResult?
  ) rethrows -> [ElementOfResult] {
    var result: [ElementOfResult] = []
    for element in self {
      if let newElement = try transform(element) {
        result.append(newElement)
      }
    }
    return result
  }

SubString分析

  • append、lowercased、uppercased
  • https://github.com/apple/swift/blob/master/stdlib/public/core/Substring.swift

append底層源碼:

@inlinable // specialize
  public mutating func append<S: Sequence>(contentsOf elements: S)
  where S.Element == Character {
    var string = String(self)
    self = Substring() // Keep unique storage if possible
    string.append(contentsOf: elements)
    self = Substring(string)
  }

owercased、uppercased的底層源碼:

extension Substring {
  public func lowercased() -> String {
    return String(self).lowercased()
  }

  public func uppercased() -> String {
    return String(self).uppercased()
  }

  public func filter(
    _ isIncluded: (Element) throws -> Bool
  ) rethrows -> String {
    return try String(self.lazy.filter(isIncluded))
  }
}

Optional分析

  • map、flatMap、==、??
  • https://github.com/apple/swift/blob/master/stdlib/public/core/Optional.swift

map底層源碼:

@inlinable
  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
    }
  }

flatMap底層源碼:

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

map和flatMap代碼結果對比:

var age: Int? = 10
var age2 = age.map { Optional.some($0 + 2)} //age2類型爲Int??
var age3 = age.flatMap{Optional.some($0 + 2)} //age3類型爲Int?

==的底層源碼:

左邊是可選型,右邊是nil

public static func ==(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool {
    switch lhs {
    case .some:
      return false
    case .none:
      return true
    }
  }

左邊是nil,右邊是可選型

public static func ==(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool {
    switch rhs {
    case .some:
      return false
    case .none:
      return true
    }
  }

兩邊都是可選型

public static func ==(lhs: Wrapped?, rhs: Wrapped?) -> Bool {
    switch (lhs, rhs) {
    case let (l?, r?):
      return l == r
    case (nil, nil):
      return true
    default:
      return false
    }
  }

三種底層代碼調用的對比:

extension Optional where Wrapped: Equatable {
    public static func ==(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool {
      switch lhs {
      case .some:
        return false
      case .none:
        return true
      }
    }
    public static func ==(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool {
      switch rhs {
      case .some:
        return false
      case .none:
        return true
      }
    }
    public static func ==(lhs: Wrapped?, rhs: Wrapped?) -> Bool {
      switch (lhs, rhs) {
      case let (l?, r?):
        return l == r
      case (nil, nil):
        return true
      default:
        return false
      }
    }
}

var age1: Int??? = nil
var age2: Int?   = nil
print(age1 == age2) //false 進入 == 方法後,age1爲Int???類型, age2轉化爲Int???, 解包後age1爲nil,age2爲可選型,所以不等

var age3: Int??? = 10
var age4: Int?   = 10
print(age3 == age4) //true 進入 == 方法後,age3爲Int???類型, age4轉化爲Int???, 解包後age3爲10,age4爲10,比的是值,所以相等

??的底層源碼:

左右兩邊可選型不一致(問號數不一致):

public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
    rethrows -> T {
  switch optional {
  case .some(let value):
    return value
  case .none:
    return try defaultValue()
  }
}

左右兩邊可選型一致(問號數一致):

public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?)
    rethrows -> T? {
  switch optional {
  case .some(let value):
    return value
  case .none:
    return try defaultValue()
  }
}

上面兩種方法的調用對比:

public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
    rethrows -> T {
  switch optional {
  case .some(let value):
    return value
  case .none:
    return try defaultValue()
  }
}
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?)
    rethrows -> T? {
  switch optional {
  case .some(let value):
    return value
  case .none:
    return try defaultValue()
  }
}

var age1: Int? = 10
var age2: Int = 10
print(age1 ?? age2) //10

var age3: Int?? = 10
var age4: Int? = 10
print(age3 ?? age4) //Optional(10)

var age5: Int?? = nil
var age6: Int = 10
print(age5 ?? age6) //Optional(10)

Metadata分析

  • 文檔: https://github.com/apple/swift/blob/master/docs/ABI/TypeMetadata.rst
  • 其他參考:
  • https://github.com/apple/swift/blob/master/include/swift/ABI/Metadata.h
  • https://github.com/apple/swift/blob/master/include/swift/ABI/MetadataKind.def
  • https://github.com/apple/swift/blob/master/include/swift/ABI/MetadataValues.h
  • https://github.com/apple/swift/blob/master/include/swift/Reflection/Records.h

通過Metadata我們可以獲得類和結構體的屬性還有屬性類型等信息,可以用來字典轉模型(JSON->Model)和模型轉字典(Model->JSON).


反射

  • 反射是編程語言中一項強大的能力,比如Java語言的反射機制
  1. 對於任意一個類型,都能夠動態獲取這個類的所有屬性和方法信息 
  2. 對於任意一個實例,都能夠動態調用它的任意方法和屬性
  • Swift的反射機制目前還比較弱,通過 Mirror 類型來提供簡單的反射功能

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章