(As I prepared and almost finished writing up the question, re-reading the appropriate language guide section answered it for me, but possibly the Q&A can be of use for others, so I'll post it nonetheless)
Background
Consider the following enum
, with cases that have one of two different types of associated values, Int
or String
:
enum Foo {
case bar(Int)
case baz(Int)
case bax(Int)
case fox(String)
}
When performing pattern matching in a switch
statement, we may construct compound cases, each covering several possible matching patterns (entering the case
branch if any of the patterns match):
func foo(_ foo: Foo) -> Int {
switch foo {
case .bar, .baz, .bax: return 42
case .fox: return 0
}
}
Just like non-compound cases, compound cases may also include value binding:
func foo(_ foo: Foo) -> Int {
switch foo {
case .bar(let x), .baz(let x), .bax(let x): return x
case .fox(let y): return Int(y) ?? 0
}
}
// or
func foo(_ foo: Foo) -> Int {
switch foo {
case let .bar(x), let .baz(x), let .bax(x): return x
case let .fox(y): return Int(y) ?? 0
}
}
Question
enum
cases that have the same type of associated value?E.g., in the latter value binding examples above, some way to use a single binding functionality for the common-type associated value in the compound case
// not valid
func foo(_ foo: Foo) -> Int {
switch foo {
case .bar, .baz, .bax, (let x): return x
case .fox: return 0
}
}
No, this is not possible; in the value binding examples above, x
must be bound in every pattern, and this must hold separately for every pattern in the compound cases.
Quoting the Language Guide - Control Flow [emphasis mine]
Compound cases can also include value bindings. All of the patterns of a compound case have to include the same set of value bindings, and each binding has to get a value of the same type from all of the patterns in the compound case. This ensures that, no matter which part of the compound case matched, the code in the body of the case can always access a value for the bindings and that the value always has the same type.
I we try to omit the binding in one of the patterns in the compound example above, we are given quite an self-explanatory error message on the subject:
func foo(_ foo: Foo) -> Int {
switch foo {
case .bar(_), .baz(let x), .bax(let x): return x
case .fox: return 0
}
}
error: 'x' must be bound in every pattern
This holds even if we don't use x
in the body that follows
func foo(_ foo: Foo) -> Int {
switch foo {
case .bar(_), .baz(let x), .bax(let x): return 0
case .fox: return 0
}
} // same error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With