In my Swift 4.2.1 code I have this enumeration:
enum MyEnum {
case caseOne(Int)
case caseTwo(String)
case caseThree
}
It conforms to Equatable
:
extension MyEnum: Equatable {
static func == (lhs: MyEnum, rhs: MyEnum) -> Bool {
switch (lhs, rhs) {
case (.caseOne, .caseOne), (.caseTwo, .caseTwo), (.caseThree, .caseThree):
return true
default:
return false
}
}
}
I need to make it conform to Hashable
, that's why I added an extension:
extension MyEnum: Hashable {
var hashValue: Int {
switch self {
case .caseOne:
return 1
case .caseTwo:
return 2
case .caseThree:
return 3
}
}
}
Now I want to migrate to the new API available in Xcode 10. I removed my implementation of hashValue
and added the implementation of hash(into:)
:
extension MyEnum: Hashable {
func hash(into hasher: inout Hasher) {
switch self {
case .caseOne:
hasher.combine(1)
case .caseTwo:
hasher.combine(2)
case .caseThree:
hasher.combine(3)
}
}
}
Could you please tell me if I switched correctly to the new API? I use this test, it prints true
twice if everything works fine:
var testDictionary = [MyEnum: Int]()
testDictionary[.caseOne(100)] = 100
testDictionary[.caseOne(1000)] = 1000
testDictionary[.caseTwo("100")] = 100
testDictionary[.caseTwo("1000")] = 1000
let countCaseOne = testDictionary.reduce(0) {
if case .caseOne = $1.key {
return $0 + 1
}
return $0
} == 1
print(countCaseOne) // true
let countCaseTwo = testDictionary.reduce(0) {
if case .caseTwo = $1.key {
return $0 + 1
}
return $0
} == 1
print(countCaseTwo) // true
You can use autogenerated Hashable
conformance, as proposed in the other answer (under condition your type doesn't contains any date of non-Hashable
types).
But that's what you can do in the general case(autogenerated code would probably look like that too):
extension MyEnum: Hashable {
func hash(into hasher: inout Hasher) {
switch self {
case .caseOne(let value):
hasher.combine(value) // combine with associated value, if it's not `Hashable` map it to some `Hashable` type and then combine result
case .caseTwo(let value):
hasher.combine(value) // combine with associated value, if it's not `Hashable` map it to some `Hashable` type and then combine result
case .caseThree:
// you can `combine` with some `Hashable` constant, but here it's ok just to skip
break
}
}
}