Swift 命名空間

以前在使用 Kingfisher、RxSwift 的時候,一直對 .rx 及 .kf 的實現比較疑惑,不知道其實現原理。swift

這篇文章咱們就來打造一個專屬本身的命名空間。bash

介紹

Swift 的命名空間是基於 module 而不是在代碼中顯式地指明,每一個 module 表明了 Swift 中的一個命名空間。也就是說,同一個 target 裏的類型名稱仍是不能相同的。app

// MyFramework.swift
// 這個文件存在於 MyFramework.framework 中
public class MyClass {
    public class func hello() {
        print("hello from framework")
    }
}

// MyApp.swift
// 這個文件存在於 app 的主 target 中
class MyClass {
    class func hello() {
        print("hello from app")
    }
}
複製代碼

在可能出現衝突的地方,咱們須要在類型名稱前面加上 module 的名字 (也就是 target 的名字):函數

// 使用哪一個 MyClass,取決因而在哪一個 target 中調用
MyClass.hello()

// hello from framework
MyFramework.MyClass.hello()
複製代碼

本身的命名空間

上面的說明雖然爲咱們解決了命名衝突的問題,可是咱們應該怎樣實現相似於 .rx、.kf 這樣本身的命名空間呢?ui

下面咱們就來一步步講解。spa

原理

原理: 對原類型進行一層封裝。而後,對這個封裝進行自定義的方法擴展。code

如今你可能不太理解,下面咱們就一步步的來實現本身的命名空間。對象

代碼實現

  • 定義一個泛型類

對原類型進行一層封裝ip

// 定義泛型類
// 首先定義一個泛型類 JTKit,使用泛型 Base
public struct JTKit<Base> {
    private let base: Base
    public init(_ base: Base) {
        self.base = base
    }
}
複製代碼
  • 定義泛型協議

定義了一個 JTWrappable 協議,這個協議表明了支持 namespace 形式的擴展。並緊接着給這個協議 extension 了默認實現。這樣實現了這個協議的類型就不須要自行實現協議所約定的內容了。ci

// 定義泛型協議
// 定義支持泛型的協議 JTWrappable,並經過協議擴展提供協議的默認實現,返回實現泛型類 JTKit 的對象自身。
public protocol JTWrappable {
    associatedtype WrappableType
    
    var jt: WrappableType { get }
}

// 協議的擴展
public extension JTWrappable {
    var jt: JTKit<Self> {
        get { return JTKit(self) }
    }
}
複製代碼

associatedtype: 相關類型。意思也就是被associatedtype關鍵字修飾的變量,至關於一個佔位符,而不能表示具體的類型。具體的類型須要讓實現的類來指定。

  • 實現命名空間 jt

須要實現命名空間的類提供 JTWrappable 協議擴展,並實現相關命名空間的對象方法(主要是擴展新的方法,如代碼中的 testMethod 方法)

extension String: JTWrappable {}

// String 命名空間 jt 中的函數
extension JTKit where Base == String {
    public var testMethod: String {
        return base + "namespace"
    }
    
    public func method(str: String) -> String {
        return base + str
    }
}
複製代碼
  • 使用
let str = "Hello "
print(str.jt.testMethod)
print(str.jt.method(str: "namespace"))

---輸出結果:---
Hello namespace
Hello namespace
複製代碼

參考資料

Swifter 100 個 SWift 必備 Tips

Versatile namespace in Swift

相關文章
相關標籤/搜索