44

I'm trying to create a dictionary of the sort [petInfo : UIImage]() but I'm getting the error Type 'petInfo' does not conform to protocol 'Hashable'. My petInfo struct is this:

struct petInfo {
    var petName: String
    var dbName: String
}

So I want to somehow make it hashable but none of its components are an integer which is what the var hashValue: Int requires. How can I make it conform to the protocol if none of its fields are integers? Can I use the dbName if I know it's going to be unique for all occurrences of this struct?

MarksCode
  • 8,074
  • 15
  • 64
  • 133

2 Answers2

65

Simply return dbName.hashValue from your hashValue function. FYI - the hash value does not need to be unique. The requirement is that two objects that equate equal must also have the same hash value.

struct PetInfo: Hashable {
    var petName: String
    var dbName: String

    var hashValue: Int {
        return dbName.hashValue
    }

    static func == (lhs: PetInfo, rhs: PetInfo) -> Bool {
        return lhs.dbName == rhs.dbName && lhs.petName == rhs.petName
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 1
    Oh good to know! Do you mind explaining the `static func` thing you added please? – MarksCode Feb 01 '17 at 05:21
  • 1
    Hashable extends Equatable. See the documentation for the two protocols for a full explanation of the `==` function. – rmaddy Feb 01 '17 at 05:22
35

As of Swift 5 var hashValue:Int has been deprecated in favour of func hash(into hasher: inout Hasher) (introduced in Swift 4.2), so to update the answer @rmaddy gave use:

func hash(into hasher: inout Hasher) {
    hasher.combine(dbName)
}
ChrisH
  • 4,468
  • 2
  • 33
  • 42
  • 5
    You should just say `hasher.combine(dbName)` since `String` already inherits from `Hashable`. Also, you need to implement the == operator, and "the components used for hashing must be the same as the components compared in your type’s == operator implementation", defined [here](https://developer.apple.com/documentation/swift/hashable/2995575-hash). – jangelsb Mar 30 '20 at 23:40
  • @jangelsb good point about `String` - updated. Not going to expand this answer on the `Hashable` protocol in general as it's really just an addendum to the original answer. – ChrisH Mar 31 '20 at 21:05
  • 1
    @jangelsb comment is gold! Implementing the `==` is absolutely necessary to get it work. – ixany Apr 16 '20 at 17:59