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

相关文章
相关标签/搜索