我有以下协议:
protocol Cacheable { //....// func identifier() -> String }
我可以让Cacheable实现Equatable吗?
当我做以下:
extension Cacheable: Equatable {} func ==(lhs:Cacheable,rhs:Cacheable) -> Bool { return lhs.identifier() == rhs.identifier() }
我得到这个错误消息:协议的扩展Cacheable不能有继承子句
1)允许比较相同类型的两个缓存
protocol Cacheable: Equatable { //....// func identifier() -> String } func ==<T : Cacheable>(lhs: T,rhs: T) -> Bool { return lhs.identifier() == rhs.identifier() }
优点
这是最简单的解决方案。
缺点
您只能比较两个相同类型的Cacheable对象。这意味着下面的代码将失败,为了修复它,你需要使动物符合缓存:
class Animal { } class Dog: Animal,Cacheable { func identifier() -> String { return "object" } } class Cat: Animal,Cacheable { func identifier() -> String { return "object" } } let a = Dog() let b = Cat() a == b //such comparison is not allowed
2)允许比较任何类型的高速缓存
protocol Cacheable:Equatable { //....// func identifier() -> String } func ==<T:Cacheable>(lhs: T,rhs: T) -> Bool { return lhs.identifier() == rhs.identifier() } func !=<T:Cacheable>(lhs: T,rhs: T) -> Bool { return lhs.identifier() != rhs.identifier() } func ==<T:Cacheable,U:Cacheable>(lhs: T,rhs: U) -> Bool { return lhs.identifier() == rhs.identifier() } func !=<T:Cacheable,rhs: U) -> Bool { return lhs.identifier() != rhs.identifier() }
优点
删除上面对于解决方案1的限制。现在你可以很容易地比较狗和猫。
缺点
>实现更长。实际上,我不知道为什么只指定==函数是不够的 – 这可能是一个编译器的错误。无论如何,你必须提供的==和!=的实现。
>在某些情况下,这种实现的好处也可能造成一个问题,因为你允许绝对不同的对象之间的比较,编译器是完全正确的。
3)不符合等式
protocol Cacheable { //....// func identifier() -> String } func ==(lhs: Cacheable,rhs: Cacheable) -> Bool { return lhs.identifier() == rhs.identifier() } func !=(lhs: Cacheable,rhs: Cacheable) -> Bool { return lhs.identifier() != rhs.identifier() }
优点
你可以使用Cacheable作为类型,而不需要任何泛型。这引入了一系列全新的可能性。例如:
let c:[Cacheable] = [Dog(),RaceCar()] c[0] == c[1] c[0] != c[1]
使用解决方案1和2这样的代码将失败,你必须在你的类中使用泛型。但是,使用最新的实现,Cacheable被视为一种类型,所以允许你声明一个类型为[Cacheable]的数组。
缺点
您不再声明符合Equatable,因此任何接受Equatable参数的函数都不会接受Cacheable。显然,除了==和!=我们声明他们为缓存。