En mi código Swift 4.2.1 tengo esta enumeración:
enum MyEnum { case caseOne(Int) case caseTwo(String) case caseThree } Se ajusta a 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 } } } Necesito que se ajuste a Hashable , por eso agregué una extensión:
extension MyEnum: Hashable { var hashValue: Int { switch self { case .caseOne: return 1 case .caseTwo: return 2 case .caseThree: return 3 } } } Ahora quiero migrar a la nueva API disponible en Xcode 10. Eliminé mi implementación de hashValue y agregué la implementación de 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) } } } ¿Podría decirme si cambié correctamente a la nueva API? Uso esta prueba, se imprime true dos veces si todo funciona bien:
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) // truePuede usar la conformidad Hashable , como se propone en la otra respuesta (bajo la condición de que su tipo no contenga ninguna fecha de tipos no Hashable ).
Pero eso es lo que puede hacer en el caso general (el código autogenerado probablemente también se vería así):
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 } } }No es necesario implementar manualmente la conformidad con Hashable , el compilador puede sintetizar automáticamente eso para su enum específica (donde todos los casos con valores asociados tienen un valor asociado con Hashable ). Solo necesita declarar conformidad.
enum MyEnum: Hashable { case caseOne(Int) case caseTwo(String) case caseThree } // You don't even need to write `: Equatable`, since automatic Hashable conformance takes care of Equatable too, I just left it there for clarity 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 } } }