Swift源碼簡介
- Swift於2015年正式開源,github地址: https://github.com/apple/swift
- 幾個可能會經常看的目錄
- docs:一些文檔
- stdlib:Swift源碼
- lib:C++源碼
- 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語言的反射機制
- 對於任意一個類型,都能夠動態獲取這個類的所有屬性和方法信息
- 對於任意一個實例,都能夠動態調用它的任意方法和屬性
- Swift的反射機制目前還比較弱,通過 Mirror 類型來提供簡單的反射功能