zoukankan      html  css  js  c++  java
  • Swift3命名空间的实现

    最近在看一些Swift开源库的时候,发现了一些优秀的开源库都使用了命名空间,例如Kingfisher这个开源库中,就针对UIImage,UIImageView,UIButton做了命名空间的扩展。通过logoImageView.kf.setImage(url)这种方式能够很好地避免扩展的命名冲突,而且相对 logoImageView.kf_setImage(url)这种通过前缀避免命名冲突的方式,具有更好的可读性,而且更Swifty化。

    实现原理

    主要通过三点来实现:

    • 泛型类
    • 泛型协议
    • 协议扩展

    分析

    这是演示代码:

    // 定义泛型类
    public final class YKKit<Base> {
        public let base: Base
        public init(_ base: Base) {
            self.base = base
        }
    }
    
    // 定义泛型协议
    public protocol YKKitCompatible {
        associatedtype CompatibleType
        var yk: CompatibleType { get }
    }
    
    // 协议的扩展 
    public extension YKKitCompatible {
        public var yk: YKKit<Self>{
            get { return YKKit(self) }
        }
    }
    
    // 实现命名空间yk
    extension String: YKKitCompatible {}
    
    // String命名空间yk中的函数
    extension YKKit where Base == String {
        // MARK: - Localized
    
        /// 国际化值
        public var localized: String {
            return NSLocalizedString(base, comment: "")
        }
    
    }
    
    // 使用
    let string = "abcd".yk.localized
    
    

    简单解析一下实现代码,主要用到了protocol和generic来实现,而且实现有点绕。

    首先定义一个泛型类YKKit,使用泛型Base

    然后定义支持泛型的协议YKKitCompatible,并通过协议扩展提供协议的默认实现,返回实现泛型类YKKit的对象自身。

    然后对需要实现命名空间的类提供YKKitCompatible协议扩展,并实现相关命名空间的对象方法(主要是扩展新的方法,如代码中的localized方法)。

    整个过程比较绕,主要还是通过协议来划分命名空间,只有遵循协议的类才拥有该命名空间,这可能需要进一步理解。



    作者:星___尘
    链接:https://www.jianshu.com/p/7808aacc0e42
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    React生命周期, 兄弟组件之间通信
    React组件式编程Demo-用户的增删改查
    React之this.refs, 实现数据双向绑定
    CCF CSP 201812-4 数据中心
    CCF CSP 201812-4 数据中心
    PAT 顶级 1020 Delete At Most Two Characters (35 分)
    PAT 顶级 1020 Delete At Most Two Characters (35 分)
    Codeforces 1245C Constanze's Machine
    Codeforces 1245C Constanze's Machine
    CCF CSP 201712-4 行车路线
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9700815.html
Copyright © 2011-2022 走看看