Swift 协议实现前缀效果:
在OC中,为了区分系统的方法名,我们会给自己的方法添加前缀。Swift中也是,但是大部分第三方框架的前缀效果都像下面这种效果:
view.snp.makeConstraintszhe // snp就是所谓的前缀
这种前缀效果看着很高级、这也是swift的一大亮点,实现起来就是给view添加前缀属性,实际上Swift标准库也是这么做的:
-
定义自己的前缀类型、给String扩展计算属性(注:extension中不能添加实例属性)
struct ETSpace{} extension String{ var et:ETSpace{ ETSpace()} }
-
有了前缀,然后给增加前缀方法,可以通过扩展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")]