你应该三思而后行,考虑是否需要将协议符合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??")
}
你提到了在==
的实现中进行类型检查,但问题是你对这两种类型没有更多的信息,除了它们都是Pet
,而且你不知道可能是Pet
的所有东西(也许稍后会添加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
不合乎逻辑的信息。
最好的方法是仅在类/结构体本身上实现相等性,并使用另一种机制进行类型检查。
isEqual
选项(来自Java),但希望保持简单,因为我有一个情况,其中有不同的类代表相同的上下文事物,因此我希望它们被视为相等,即使它们是不同的实现。 - drekka