简体   繁体   中英

How to conform custom class with optional properties to “hashable” protocol

Suppose I have a base class "Person" that I want to add to a Set (List) and need to therefore conform to Hashable and 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
}

This class has only a single optional property, which makes the dealing with the optional in the creation of the hashvalue fairly reasonable. What if there were 2 or more optional properties? I can see this getting out of hand quite quickly.

How are optional properties generally dealt with when conforming an object to the hashable protocol?

The calculation of the hash value does not have to be based on all properties. In fact, it doesn't need to be based on any. You could simply return a hard coded number though you shouldn't.

Simply return a hash value of one or more of the non-optional properties.

The only rule is that two objects that compare as equal must also return the same hash value. But there is no requirement that two objects with the same hash value much compare as equal.

Would just like to add that a class does not need to conform to the Hashable or Equatable protocol to be used as the elements of an Array (which is what I assumed you meant by a List). It is only necessary to conform to Hashable and therefore Equatable, if you want to use the class as an element in a Set or as a Key for a Dictionary. As specified in the API reference of Hashable :

You can use any type that conforms to the Hashable protocol in a set or as a dictionary key.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM