假设我有一个基类“Person”,我想添加到Set(List),因此需要符合Hashable和Equatable:
class Person : Equatable, Hashable {
let firstName: String
let lastName: String
var nickname: String?
let dateOfBirth: NSDate
var hashValue: Int {
if let nickname = nickname {
return firstName.hashValue ^
lastName.hashValue ^
nickname.hashValue ^
dateOfBirth.hashValue
} else {
return firstName.hashValue ^
lastName.hashValue ^
dateOfBirth.hashValue
}
}
init (firstName: String, lastName: String, nickname: String, bornOn dateOfBirth: NSDate) {
self.firstName = firstName
self.lastName = lastName
self.nickname = nickname
self.dateOfBirth = dateOfBirth
}
}
func ==(lhs: Person, rhs: Person) -> Bool {
return
lhs.firstName == rhs.firstName &&
lhs.lastName == rhs.lastName &&
lhs.nickname == rhs.nickname &&
lhs.dateOfBirth == rhs.dateOfBirth
}
这个类只有一个可选属性,这使得在创建hashvalue时处理可选属性相当合理。如果有2个或更多可选属性怎么办?我可以很快看到这种情况失控。
在将对象符合可扩展协议时,通常如何处理可选属性?
答案 0 :(得分:5)
哈希值的计算不必基于所有属性。事实上,它并不需要基于任何。您可以简单地返回硬编码的数字,但您不应该这样做。
只需返回一个或多个非可选属性的哈希值。
唯一的规则是两个比较相等的对象也必须返回相同的哈希值。但是没有要求具有相同散列值的两个对象比较相同。
答案 1 :(得分:0)
只想补充说一个类不需要符合Hashable或Equatable协议就可以用作数组的元素(这就是我认为你的List的意思)。如果要将类用作Set中的元素或作为Dictionary的键,则只需要符合Hashable并因此符合Equatable。正如API reference of Hashable:
中所述您可以在集合中使用符合Hashable协议的任何类型 或作为字典键。