代码之家  ›  专栏  ›  技术社区  ›  Dorukhan Arslan

包含所有扩展方法的Swift模块

  •  0
  • Dorukhan Arslan  · 技术社区  · 6 年前

    我个人更喜欢Swift中带有前缀的扩展方法。乍一看,可以更容易地猜测函数是来自原始类还是来自扩展。而且,它使框架在其他项目中更易于重用。我们不需要搜索框架方法所属的名称空间。但是,在扩展中为所有实例和静态方法添加前缀有点详尽。因此,我想创建一个包含所有扩展方法的模块,不管它是实例还是静态的。

    我看了一下 this implementation ,并喜欢它,但不幸的是,它只适用于实例方法:

    public protocol MyHelperCompatible {
        associatedtype someType
        var my: someType { get }
    }
    
    public extension MyHelperCompatible {
        public var my: MyHelper<Self> {
            get { return MyHelper(self) }
        }
    }
    
    public struct MyHelper<Base> {
        let base: Base
        init(_ base: Base) {
            self.base = base
        }
    }
    
    // All conformance here
    extension UIColor: MyHelperCompatible { }
    

    使用此功能,我们可以按如下方式访问实例方法:

    let redImage = UIColor.red.my.toImage()
    

    您知道如何应用类似的逻辑来添加模块来处理实例和静态方法吗(例如。, UIColor.my.staticMethod() )你建议用什么方法解决这个问题?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Cristik    6 年前

    受RxSwift继续使用的方法的启发,下面是一个提供对 my 分机。

    首先,让我们声明扩展的基础:

    struct MyExtension<Target> {
        let target: Target
    
        init(_ target: Target) {
            self.target = target
        }
    }
    

    protocol MyExtensionCompatible { }
    
    extension MyExtensionCompatible {
        // instance extension
        var my: MyExtension<Self> { return MyExtension(self) }
    
        // static extension
        static var my: MyExtension<Self>.Type { return MyExtension<Self>.self }
    }
    

    现在让我们开始播放并添加 UIColor 一致性:

    extension UIColor: MyExtensionCompatible { }
    
    extension MyExtension where Target == UIColor {
    
        static var customColor: UIColor { return UIColor.blue }
    
        func toImage() -> UIImage {
            return UIImage()
        }
    }
    

    最后,让我们使用上面创建的所有内容:

    // the static property
    let color = UIColor.my.customColor
    
    // the instance function
    let colorImage = color.my.toImage()
    
    // foldoesn't compile, compile, we haven't declared UILabel as compatible
    let color2 = UILabel.my