我有以下Protocol
:
protocol Cacheable {
//....//
func identifier() -> String
}
我可以让Cacheable
实现Equatable吗?
当我执行以下操作时:
extension Cacheable: Equatable {}
func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {
return lhs.identifier() == rhs.identifier()
}
我收到以下错误消息:协议扩展Cacheable
不能有继承条款
答案 0 :(得分:46)
status
进行比较Cacheable
这是最简单的解决方案。
您只能比较两个相同类型的protocol Cacheable: Equatable {
//....//
func identifier() -> String
}
func ==<T : Cacheable>(lhs: T, rhs: T) -> Bool {
return lhs.identifier() == rhs.identifier()
}
个对象。这意味着以下代码将失败,为了解决此问题,您需要使Cacheable
符合Animal
:
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
Cacheable
删除上述解决方案1的限制。现在,您可以轻松地比较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, U:Cacheable>(lhs: T, rhs: U) -> Bool {
return lhs.identifier() != rhs.identifier()
}
和Dog
。
Cat
函数是不够的 - 这可能是编译器的错误。无论如何,您必须为==
和==
提供实施。!=
Equatable
您可以使用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
使用解决方案1和2这样的代码会失败,您必须在类中使用泛型。但是,最新的实现let c:[Cacheable] = [Dog(),RaceCar()]
c[0] == c[1]
c[0] != c[1]
被视为一种类型,因此您可以声明一个类型为Cacheable
的数组。
您不再声明与[Cacheable]
的一致性,因此任何接受Equatable
参数的函数都不会接受Equatable
。显然,除了Cacheable
和==
之外我们为!=
s声明了它们。
如果这不是您的代码中的问题,我实际上更喜欢这个解决方案。能够将协议视为一种类型在许多情况下非常有用。
答案 1 :(得分:11)
尝试。
extension Equatable where Self : Cacheable {
}