How to Implement hash(into:) from hashValue in Swift?
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)
}
Swift: 'Hashable.hashValue' is deprecated as a protocol requirement;
As the warning says, now you should implement the hash(into:)
function instead.
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
}
}
It would be even better (in case of enums and struct) to remove the custom hash(into:)
implementation (unless you need a specific implementation) as the compiler will automatically synthesize it for you.
Just make your enum conforming to it:
public enum ActiveType: Hashable {
case mention
case hashtag
case url
case custom(pattern: String)
var pattern: String {
switch self {
case .mention: return RegexParser.mentionPattern
case .hashtag: return RegexParser.hashtagPattern
case .url: return RegexParser.urlPattern
case .custom(let regex): return regex
}
}
}
Hashable.hashValue' is deprecated as a protocol requirement; conform type 'CarnivalWheel' to 'Hashable' by implementing 'hash(into:)' instead
func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
}
will add conformance.
why do i receive this warning to implement 'hash(into:)' on a type that conforms to a protocol with at default implementation
This code has two default implementations for hash(into:)
. One from Int, and one from SettingSelectable.
I'm not certain if this is defined behavior. My expectation is that the Int implementation is used and the SettingsSelectable extension is ignored. In any case, the diagnostic is not very good. I suggest opening a defect about that.
You can fix this error by removing the Int
, or by explicitly implementing hash(into:)
so it's clear which one you mean. Or you could create another layer of protocols:
protocol SettingsSelectableBase: Hashable, Settingsable {
var display: String { get }
}
protocol SettingsSelectable: SettingsSelectableBase {}
// Only give the default to things that ask for it, not to Base conformers
extension SettingsSelectable {
func hash(into hasher: inout Hasher) {
hasher.combine(display)
}
}
extension SettingsSelectableBase {
func resetSettings() {
print("These have been reset")
}
}
enum PlaybackSpeed: Int, SettingsSelectableBase { ... }
Implementing a hash combiner in Swift
You cannot define a parameter of type P
if P
is a protocol which has Self
or associated type requirements.
In this case it is the Equatable
protocol from which Hashable
inherits, which has a Self
requirement:
public static func ==(lhs: Self, rhs: Self) -> Bool
What you can do is to define a generic method instead:
extension Hashable {
func combineHash<T: Hashable>(with hashableOther: T) -> Int {
let ownHash = self.hashValue
let otherHash = hashableOther.hashValue
return (ownHash << 5) &+ ownHash &+ otherHash
}
}
Related Topics
Value for Swift_Version Cannot Be Empty
Hide Tab Bar in View with Push
Why Are Iboutlets Optionals After Swift 5 Migration
Catch Objective-C Exception in Swift
How to Automatically Reflect Coredata+Icloud Changes in Swiftui View
Swift3:How to Handle Precedencegroup Now Operator Should Be Declare with a Body
Apple MACh-O Linker Error, After Changing Project Name
Using a Mtltexture as the Environment Map of a Scnscene
Swift: How to Expand a Tilde in a Path String
Convert Swift Dictionary to String
Show/Hide Password - How to Add This Feature
Realitykit - Set Text Programmatically of an Entity of Reality Composer
Wcsession Has Not Been Activated
How to Test That Statictexts Contains a String Using Xctest