Swift利用协议实现前缀功能
想要实现的功能
计算字符串中数字的个数
var greeting = "1234-Hello, playground-1234"
extension String {
    var numberCount: Int {
        var number = 0
        for c in self where ("0"..."9").contains(c){
            number += 1
        }
        return number
    }
}
print(greeting.numberCount)
存在的问题
直接给一个类增加扩展,容易导致冲突。
解决方案
属性前增加前缀(不优雅)
var greeting = "1234-Hello, playground-1234"
extension String {
    var zy_numberCount: Int {
        var number = 0
        for c in self where ("0"..."9").contains(c){
            number += 1
        }
        return number
    }
}
print(greeting.zy_numberCount)
点语法增加前缀
print(greeting.zy.numberCount)
一、持有属性方式
- 结构体ZY持有str,并在构造方法中初始化
- 字符串扩展持有zy计算属性
缺点:
- 不灵活,比如无法给数组扩展功能
var greeting = "1234-Hello, playground-1234"
struct ZY {
    var str: String
    init(_ str: String) {
        self.str = str
    }
    var numberCount: Int {
        var number = 0
        for c in str where ("0"..."9").contains(c){
            number += 1
        }
        return number
    }
    
    func test() {
        print("---test---")
    }
}
extension String {
    var zy: ZY { ZY(self) }
}
print(greeting.zy.numberCount)
greeting.zy.test()
二、使用范型
缺点:使用繁琐,需要给每一个类扩充功能
var greeting = "1234-Hello, playground-1234"
struct ZY<Base> {
    var base: Base
    init(_ base: Base) {
        self.base = base
    }
}
extension String {
    var zy: ZY<String> { ZY(self) }
}
class People {}
extension People {
    var zy: ZY<People> { ZY(self) }
}
extension ZY where Base == String {
    var numberCount: Int {
        var number = 0
        for c in base where ("0"..."9").contains(c){
            number += 1
        }
        return number
    }
    
    func test() {
        print("---test---")
    }
}
extension ZY where Base: People {
    func run()  {
        print("person run")
    }
}
print(greeting.zy.numberCount)
greeting.zy.test()
var person = People()
person.zy.run()
给String扩充类型方法
struct ZY<Base> {
    var base: Base
    init(_ base: Base) {
        self.base = base
    }
}
extension String {
    var zy: ZY<String> { ZY(self) }
    static var zy: ZY<String>.Type { ZY<String>.self }
}
extension ZY where Base == String {
    var numberCount: Int {
        var number = 0
        for c in base where ("0"..."9").contains(c){
            number += 1
        }
        return number
    }
    
    func test() {
        print("---test---")
    }
    
    static func staticTest() {
        print("---static test---")
    }
}
String.zy.staticTest()
三、利用协议实现前缀
var greeting = "1234-Hello, playground-1234"
/// 前缀类型
struct ZY<Base> {
    var base: Base
    init(_ base: Base) {
        self.base = base
    }
}
/// 利用协议扩展前缀属性
protocol ZYCompatible {}
extension ZYCompatible {
    var zy: ZY<Self> {
        set {} // 使mutating方法编译通过
        get { ZY(self) }
    }
    static var zy: ZY<Self>.Type {
        set {} // 使mutating方法编译通过
        get { ZY<Self>.self }
    }
}
/// 给字符串扩展功能
/// 让 String 拥有 zy 前缀属性
extension String: ZYCompatible {}
/// 给string.zy、String( ).zy前缀扩展功能
extension ZY where Base == String {
    var numberCount: Int {
        var number = 0
        for c in base where ("0"..."9").contains(c){
            number += 1
        }
        return number
    }
    
    mutating func test() {
        print("---test---")
    }
    
    static func staticTest() {
        print("---static test---")
    }
}
print(greeting.zy.numberCount)
greeting.zy.test()
String.zy.staticTest()