在扩展里添加协议遵循
1 2 3 4 5 6 7 8 9 protocol TextRepresentable { var textDesc: String { get } } // 扩展已存在类遵循新协议 extension Dice: TextRepresentable { var textDesc: String { return "zhangjian" } }
有条件的遵循协议
使用扩展声明协议
如果一个 类型(类、结构体、枚举)
已经遵循了协议的所有需求,但还没有 声明它采纳这个协议,你可以通过 扩展来让它声明并采纳
这个协议
定义协议:
1 2 3 4 // 定义协议 protocol TextRepresentable { var textDesc: String { get } }
定义结构体类型:
1 2 3 4 5 6 7 struct Hamster { var name: String // 实现了 遵循协议的所有要求 var textDesc: String { return "a hamster named \(name)" } }
可以通过 扩展 来让 Hamster 遵循 协议:
1 extension Hamster: TextRepresentable {}
协议本身扩展
协议可以通过 扩展
来提供 属性、方法
,即 协议本身支持扩展
示例:
【第一步】:定义一个随机数协议
1 2 3 4 // 定义协议 protocol RandomNumberGenerator { func random() -> Double }
【第二步】:生成随机数
1 2 3 4 5 6 7 8 9 10 11 // 生成随机数 class LinearCongruentialGenerator: RandomNumberGenerator { var lastRandom = 42.0 let m = 139968.0 let a = 3877.0 let c = 29573.0 func random() -> Double { lastRandom = ((lastRandom * a + c).truncatingRemainder(dividingBy:m)) return lastRandom / m } }
【第三步】:让协议本身扩展
1 2 3 4 5 6 // 协议本身支持扩展 extension RandomNumberGenerator { func randomBool() -> Bool { return random() > 0.5 } }
【最后】:调用
1 2 3 4 5 6 7 let generator = LinearCongruentialGenerator() print("here is random number \(generator.random())") print("and here is random bool \(generator.randomBool())") ========== here is random number 0.3746499199817101 and here is random bool true
提供默认实现
给集合类和其中的元素添加 协议扩展 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // 有条件的遵循协议 protocol TextRepresentable { var textDesc: String { get } } // 定义一个结构体 Person struct Person { var name:String = "" } // 扩展 Person 遵循协议 extension Person: TextRepresentable{ var textDesc: String { return "name \(name)" } } // 扩展数组元素都遵循协议 extension Array: TextRepresentable where Element: TextRepresentable { var textDesc: String { let items = self.map { $0.textDesc } return items.joined(separator: ",") } } let array = [Person(name: "zj"),Person(name: "wxy")] print(array.textDesc) ========== name zj,name wxy
给 协议扩展 添加限制
将上面的 Array
改成 Collection协议
,查看打印结果
1 2 3 4 5 6 7 8 9 10 // 扩展数组元素都遵循协议 extension Collection where Iterator.Element: TextRepresentable { var textDesc: String { let items = self.map { $0.textDesc } return items.joined(separator: ",") } } ========== name zj,name wxy
总结
除了可以给具体的 类、结构体
扩展以外,还可以 扩展协议本身