29

I don't quite have an idea on what to do with the deprecation warning from the compiler to not use hashValue and instead implement hash(into:).

'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'MenuItem' to 'Hashable' by implementing 'hash(into:)' instead

The answer from Swift: 'Hashable.hashValue' is deprecated as a protocol requirement; has this example:

func hash(into hasher: inout Hasher) {
    switch self {
    case .mention: hasher.combine(-1)
    case .hashtag: hasher.combine(-2)
    case .url: hasher.combine(-3)
    case .custom(let regex): hasher.combine(regex) // assuming regex is a string, that already conforms to hashable
    }
}

And I do have this struct, to customise PagingItem of Parchment (https://github.com/rechsteiner/Parchment).

import Foundation

/// The PagingItem for Menus.
struct MenuItem: PagingItem, Hashable, Comparable {
    let index: Int
    let title: String
    let menus: Menus

    var hashValue: Int {
        return index.hashValue &+ title.hashValue
    }

    func hash(into hasher: inout Hasher) {
        // Help here?
    }

    static func ==(lhs: MenuItem, rhs: MenuItem) -> Bool {
        return lhs.index == rhs.index && lhs.title == rhs.title
    }

    static func <(lhs: MenuItem, rhs: MenuItem) -> Bool {
        return lhs.index < rhs.index
    }
}
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Glenn Posadas
  • 12,555
  • 6
  • 54
  • 95
  • 1
    Possibly helpful: [How can I update this Hashable.hashValue to conform to new requirements.?](https://stackoverflow.com/q/55516776/1187415). – Martin R Apr 15 '19 at 11:03

2 Answers2

61

You can simply use hasher.combine and call it with the values you want to use for hashing:

func hash(into hasher: inout Hasher) {
    hasher.combine(index)
    hasher.combine(title)
}
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
8

There are two modern options for hashValue creation.

func hash(into hasher: inout Hasher) {
  hasher.combine(foo)
  hasher.combine(bar)
}

// or

// which is more robust as you refer to real properties of your type
func hash(into hasher: inout Hasher) {
  foo.hash(into: &hasher)
  bar.hash(into: &hasher)
}
dimpiax
  • 12,093
  • 5
  • 62
  • 45
  • 1
    Just to note: The combine(_:) method is just a convenience operation that takes in a Hashable value, such as an integer or string. Behind the scenes, this combine(_:) method calls the hash(into:) method to mix its value into the Hasher state. – Yasper Dec 08 '21 at 12:57