Swift协议实现Equatable

时间:2015-08-10 14:16:29

标签: swift swift2 protocols equatable

我有以下Protocol

protocol Cacheable {
    //....//
    func identifier() -> String
}

我可以让Cacheable实现Equatable吗?

当我执行以下操作时:

extension Cacheable: Equatable {}

func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {

     return lhs.identifier() == rhs.identifier()
}

我收到以下错误消息:协议扩展Cacheable不能有继承条款

2 个答案:

答案 0 :(得分:46)

1)允许两个相同类型的status进行比较

Cacheable

赞成

这是最简单的解决方案。

缺点

您只能比较两个相同类型的protocol Cacheable: Equatable { //....// func identifier() -> String } func ==<T : Cacheable>(lhs: T, rhs: T) -> Bool { return lhs.identifier() == rhs.identifier() } 个对象。这意味着以下代码将失败,为了解决此问题,您需要使Cacheable符合Animal

Cacheable

2)允许比较任何类型的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函数是不够的 - 这可能是编译器的错误。无论如何,您必须为====提供实施。
  • 在某些情况下,这种实现的好处也可能会带来问题,因为您允许在绝对不同的对象之间进行比较,编译器完全可以使用它。

3)不符合!=

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 {
}