How to make a Swift enum with associated values equatable
SE-0185 Synthesizing Equatable and Hashable conformance has been implemented in Swift 4.1, so that it suffices do declare conformance to the protocol (if all members are Equatable
):
enum ViewModel: Equatable { case heading(String) case options(id: String, title: String, enabled: Bool)}
For earlier Swift versions, a convenient way is to use that tuples can be compared with ==
.
You many also want to enclose the compatibility code in a Swift version check, so that the automatic synthesis is used once the project is updated to Swift 4.1:
enum ViewModel: Equatable { case heading(String) case options(id: String, title: String, enabled: Bool) #if swift(>=4.1) #else static func ==(lhs: ViewModel, rhs: ViewModel) -> Bool { switch (lhs, rhs) { case (let .heading(lhsString), let .heading(rhsString)): return lhsString == rhsString case (let .options(lhsId, lhsTitle, lhsEnabled), let .options(rhsId, rhsTitle, rhsEnabled)): return (lhsId, lhsTitle, lhsEnabled) == (rhsId, rhsTitle, rhsEnabled) default: return false } } #endif}
You can add something like below, check this link for more information.Return statement for options depend on your needs.
#if swift(>=4.1)#elsefunc ==(lhs: ViewModel, rhs: ViewModel) -> Bool { switch (lhs, rhs) { case (let .heading(lhsString), let .heading(rhsString)): return lhsString == rhsString case (let .options(id1, title1, enabled1),let .options(id2, title2, enabled2)): return id1 == id2 && title1 == title2 && enabled1 == enabled2 default: return false }}#endif
Maybe not relevant for the OP but this might help others:
Remember that if you only want to compare an enum value against a fixed value, you can simply use pattern matching:
if case let ViewModel.heading(title) = enumValueToCompare { // Do something with title}
If you care about the associated value, you can add some conditions on it:
if case let ViewModel.heading(title) = enumValueToCompare, title == "SomeTitle" { // Do something with title}