如何将自定义类与可选属性符合"hashable"协议

Bra*_*enz 3 optional hashable swift

假设我有一个基类"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
}
Run Code Online (Sandbox Code Playgroud)

这个类只有一个可选属性,这使得在创建hashvalue时处理可选属性相当合理.如果有2个或更多可选属性怎么办?我可以很快看到这种情况失控.

在将对象符合可扩展协议时,通常如何处理可选属性?

rma*_*ddy 5

散列值的计算不必基于所有属性.实际上,它不需要基于任何.您可以简单地返回硬编码的数字,但不应该.

只需返回一个或多个非可选属性的哈希值.

唯一的规则是两个比较相等的对象也必须返回相同的哈希值.但是没有要求具有相同散列值的两个对象比较相同.

  • 当`=='很贵时,`hashValue`也可用于`==`的优化.如果它们的哈希值不相等,您可以快速丢弃明显不相等的值.`hashValue`应该是O(1)来计算. (2认同)