Swift 协议实现平等
Swift Protocol Implements Equatable
我有以下 Protocol
:
protocol Cacheable {
//....//
func identifier() -> String
}
我可以让 Cacheable
实现 Equatable 吗?
当我执行以下操作时:
extension Cacheable: Equatable {}
func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {
return lhs.identifier() == rhs.identifier()
}
我收到此错误消息:协议扩展 Cacheable
不能有继承子句
试试。
extension Equatable where Self : Cacheable {
}
1) 允许两个相同类型的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
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 的限制。现在您可以轻松比较 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
作为类型而不需要任何泛型。这引入了全新的可能性范围。例如:
let c:[Cacheable] = [Dog(),RaceCar()]
c[0] == c[1]
c[0] != c[1]
使用解决方案 1 和 2 这样的代码会失败,您将不得不在 类 中使用泛型。但是,在最新的实现中,Cacheable
被视为一种类型,因此您可以声明一个 [Cacheable]
.
类型的数组
缺点
您不再声明符合 Equatable
,因此任何接受 Equatable
参数的函数将不接受 Cacheable
。显然,除了我们为 Cacheable
声明的 ==
和 !=
之外。
如果这在您的代码中不是问题,我实际上更喜欢这个解决方案。在许多情况下,能够将协议视为一种类型非常有用。
我有以下 Protocol
:
protocol Cacheable {
//....//
func identifier() -> String
}
我可以让 Cacheable
实现 Equatable 吗?
当我执行以下操作时:
extension Cacheable: Equatable {}
func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {
return lhs.identifier() == rhs.identifier()
}
我收到此错误消息:协议扩展 Cacheable
不能有继承子句
试试。
extension Equatable where Self : Cacheable {
}
1) 允许两个相同类型的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
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 的限制。现在您可以轻松比较 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
作为类型而不需要任何泛型。这引入了全新的可能性范围。例如:
let c:[Cacheable] = [Dog(),RaceCar()]
c[0] == c[1]
c[0] != c[1]
使用解决方案 1 和 2 这样的代码会失败,您将不得不在 类 中使用泛型。但是,在最新的实现中,Cacheable
被视为一种类型,因此您可以声明一个 [Cacheable]
.
缺点
您不再声明符合 Equatable
,因此任何接受 Equatable
参数的函数将不接受 Cacheable
。显然,除了我们为 Cacheable
声明的 ==
和 !=
之外。
如果这在您的代码中不是问题,我实际上更喜欢这个解决方案。在许多情况下,能够将协议视为一种类型非常有用。