How to make a Swift enum with associated values equatable How to make a Swift enum with associated values equatable swift swift

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}