34

我有以下内容Protocol

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

我可以使Cacheable工具 Equatable 吗?

当我执行以下操作时:

extension Cacheable: Equatable {}

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

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

我收到此错误消息:协议扩展Cacheable不能有继承子句

4

2 回答 2

47

1) 允许Cacheable比较两个相同类型的s

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

2) 允许Cacheable比较任何类型的 s

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()
}

优点

消除上述解决方案 1 的限制。现在您可以轻松比较DogCat

缺点

  • 实施时间更长。实际上我不确定为什么只指定==函数是不够的——这可能是编译器的错误。无论如何,您必须同时提供 和 的==实现!=
  • 在某些情况下,此实现的好处也可能会带来问题,因为您允许在绝对不同的对象之间进行比较,并且编译器完全可以接受。

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用作类型而不需要任何泛型。这引入了一系列全新的可能性。例如:

let c:[Cacheable] = [Dog(),RaceCar()]

c[0] == c[1]
c[0] != c[1]

对于解决方案 1 和 2,此类代码将失败,您将不得不在类中使用泛型。但是,最新的实现Cacheable被视为一种类型,因此您可以声明一个 type 数组[Cacheable]

缺点

您不再声明符合,Equatable因此任何接受Equatable参数的函数都不会接受Cacheable==显然,除了!=我们为Cacheables 声明它们。

如果这不是您的代码中的问题,我实际上更喜欢这个解决方案。在许多情况下,能够将协议视为一种类型非常有用。

于 2015-08-10T14:26:21.113 回答
11

尝试。

extension Equatable where Self : Cacheable {
}
于 2015-08-10T14:23:13.267 回答