Swift 实现变量方法的前缀效果

Swift 协议实现前缀效果:

在OC中,为了区分系统的方法名,我们会给自己的方法添加前缀。Swift中也是,但是大部分第三方框架的前缀效果都像下面这种效果:

view.snp.makeConstraintszhe // snp就是所谓的前缀

这种前缀效果看着很高级、这也是swift的一大亮点,实现起来就是给view添加前缀属性,实际上Swift标准库也是这么做的:

  1. 定义自己的前缀类型、给String扩展计算属性(注:extension中不能添加实例属性)

    struct ETSpace{}
    
    extension String{
        var et:ETSpace{ ETSpace()}
    }
    
  2. 有了前缀,然后给增加前缀方法,可以通过扩展ETSpace,也可以直接写在结构体中

    extension ETSpace{
        func test(){
            print(#function)
        }
    }
    

这样简单的前缀就实现了,但是大部分情况下是需要对字符串处理的

可以给ETSpace添加一个变量_string记录当前字符串

struct ETSpace{
    var _string:String
    init(_ string:String) {
        _string = string
    }
}

extension String{
    var et:ETSpace{ ETSpace(self)}
}

extension ETSpace{
    func test(){
        print("ET" + "\(_string)")
    }
}

更通用的做法是设计成范型,方便其他类也适用前缀:

struct ETSpace{
    var _value:T
    init(_ value:T) {
        _value = value
    }
}

扩展其他类型,范型的具体类型用代替

extension String{
    var et:ETSpace{ ETSpace(self)}
}
extension Array{
    var et:ETSpace{ETSpace(self)}
}
extension Dictionary{
    var et:ETSpace{ETSpace(self)}
}

针对不同类新实现对应的方法:

extension ETSpace where T == String{
    func test(){
        print("ET" + "\(_value)")
    }
}
extension ETSpace where T == Array{
    func test(){
        print(_value.map {"\($0)"})
    }
}
extension ETSpace where T == Dictionary{
    func test(){
        print( _value.compactMap {$0})
    }
}

以上做法实现了前缀,但是实现上稍微麻烦了些

用协议实现:

protocol ETProtocol{
    var et:ETSpace {get}
}

extension String : ETProtocol{
    var et: ETSpace { ETSpace(self)}
}
extension Array : ETProtocol{
    var et: ETSpace {ETSpace(self)}
}
extension Dictionary : ETProtocol{
    var et:ETSpace {ETSpace(self)}
}

以后只要对应的类遵守ETProtocol协议就能适用前缀了:

var etStr = "et"
var etArr = [1,2,3,4,5,6,7,8,9]
var etDic = ["swift":"5.5","oc":"2.0"]

输出:

ETet
["1", "2", "3", "4", "5", "6", "7", "8", "9"]
[(key: "swift", value: "5.5"), (key: "oc", value: "2.0")]

你可能感兴趣的:(Swift 实现变量方法的前缀效果)