Swift Pattern Matching - multiple enum-case-pattern in guard?

874 Views Asked by At

What's the correct syntax for using enum cases and guard to allow more-than-one case to proceed?

With a switch we can use a case-item-list to combine switch cases.

Is there anything like that for guard or if statements?

Here's a code example of kinda-sorta what I'd like to do...

enum Thingy {
    case one
    case two
    case three
}

func doSomething(with value: Thingy) {
    switch value {
    case .one, .three:
        print("I like these numbers")
    default:
        print("Two")
    }
}

// Doesn't compile
func doSomethingAlt(with value: Thingy) {
    guard .one, .three = value else {
        print("Two")
        return
    }

    print("I like these numbers")
}

1

There are 1 best solutions below

3
On

You just need to give the conditions separated by an OR (||) condition. Here is how:

func doSomethingAlt(with value: Thingy) {
    guard value == .one || value == .three else {
        print("Two")
        return
    }

    print("I like these numbers")
}

This would require for the enum to conform to Equatable. Enums without associated values or with raw-type automatically conform to Equatable. Since Swift 4.1 enum cases even with associated-types automatically conform to Equatable. Here is some code:

enum Thingy: Equatable {
    case one(String)
    case two
    case three
}
func doSomethingAlt(with value: Thingy) {
    guard value == .one("") || value == .three else {
        print("Two")
        return
    }

    print("I like these numbers")
}

And, since Swift 5.1 enum associated type can have default values. Which is an awesome feature so you just need to do this:

enum Thingy: Equatable {
    case one(String = "")
    case two
    case three
}
func doSomethingAlt(with value: Thingy) {
    guard value == .one() || value == .three else {
        print("Two")
        return
    }

    print("I like these numbers")
}