您应该三思而后行的原因Equatable
是,在许多情况下它只是没有意义。考虑这个例子:
protocol Pet: Equatable {
var age: Int { get }
}
extension Pet {
static func == (lhs: Pet, rhs: Pet) -> Bool {
return lhs.age == rhs.age
}
}
struct Dog: Pet {
let age: Int
let favoriteFood: String
}
struct Cat: Pet {
let age: Int
let favoriteLitter: String
}
let rover: Pet = Dog(age: "1", favoriteFood: "Pizza")
let simba: Pet = Cat(age: "1", favoriteLitter: "Purina")
if rover == simba {
print("Should this be true??")
}
您提到在 of 的实现中进行类型检查,==
但问题是您没有关于它们之外的任何一种类型的信息Pet
s 并且您不知道所有可能是 a 的东西Pet
(也许您将添加 aBird
和Rabbit
稍后)。如果你真的需要这个,另一种方法可以建模像 C# 这样的语言如何实现平等,方法是:
protocol IsEqual {
func isEqualTo(_ object: Any) -> Bool
}
protocol Pet: IsEqual {
var age: Int { get }
}
struct Dog: Pet {
let age: Int
let favoriteFood: String
func isEqualTo(_ object: Any) -> Bool {
guard let otherDog = object as? Dog else { return false }
return age == otherDog.age && favoriteFood == otherDog.favoriteFood
}
}
struct Cat: Pet {
let age: Int
let favoriteLitter: String
func isEqualTo(_ object: Any) -> Bool {
guard let otherCat = object as? Cat else { return false }
return age == otherCat.age && favoriteLitter == otherCat.favoriteLitter
}
}
let rover: Pet = Dog(age: "1", favoriteFood: "Pizza")
let simba: Pet = Cat(age: "1", favoriteLitter: "Purina")
if !rover.isEqualTo(simba) {
print("That's more like it.")
}
在这一点上,如果你真的想要,你可以在不实施的情况==
下实施Equatable
:
static func == (lhs: IsEqual, rhs: IsEqual) -> Bool { return lhs.isEqualTo(rhs) }
在这种情况下,您必须注意的一件事是继承。因为您可以向下转换继承类型并删除可能isEqualTo
没有逻辑意义的信息。
最好的方法是只在类/结构本身上实现相等,并使用另一种机制进行类型检查。