您应该三思而后行的协议是否符合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??")
}
您提到在== 的实现中进行类型检查,但问题是除了Pets 之外,您没有关于任何一种类型的信息,而且您不知道所有可能是@ 的东西987654325@(也许您稍后会添加Bird 和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 没有逻辑意义的信息。
最好的方法是只在类/结构本身上实现相等,并使用另一种机制进行类型检查。