如何使用类型约束调用协议扩展默认实现

时间:2017-03-18 15:11:27

标签: swift protocol-extension

考虑以下示例:

class ManObj {
    func baseFunc() {
        print("ManObj baseFunc")
    }
}

class SubObj: ManObj {
}

protocol Model {
}

extension Model { // This is protocol extension
    func someFunc() { // Protocol extension default implementation
        (self as! ManObj).baseFunc()
        print("Model implementation")
    }
}
extension SubObj: Model {
    func someFunc() {
        print("SubObj Implementation")
    }
}

let list = SubObj()
list.someFunc() // static dispatching

let list2: Model = SubObj()
list2.someFunc() // dynamic dispatching

输出很好:

SubObj Implementation
ManObj baseFunc
Model implementation

但我不喜欢(self as! ManObj).baseFunc()行中的演员。

事实上,我只打算将Model协议应用于ManObj的子类。 (但并非ManObj的所有子类都是Model!)因此,我尝试将Model更改为:

extension Model where Self: ManObj {
    func someFunc() {
        self.baseFunc() // No more casting needed!
        print("Model implementation")
    }
}

但是我遇到了错误:

list2.someFunc()< - error: 'Model' is not a subtype of 'ManObj'

那么,在我约束Model.someFunclist2之后,我有办法从Model触发where Self: ManObj吗?

1 个答案:

答案 0 :(得分:0)

为类型转换创建一个空类

class ManObj {
    func baseFunc() {
        print("ManObj baseFunc")
    }
}

class SubObj: ModelCaster {
    func someFunc() {
        print("SubObj Implementation")
    }
}

protocol Model {
}

extension Model where Self: ModelCaster { // This is protocol extension
    func someFunc() { // Protocol extension default implementation
        print("Model implementation")
    }
}

class ModelCaster: ManObj, Model{

}

let list = SubObj()
list.someFunc() //SubObj Implementation

let list2: ModelCaster = SubObj()
list2.someFunc() //Model implementation