复合开关案例:对于具有相同类型关联值的复合枚举案例,我们是否可以使用单个公共值绑定?

dfr*_*fri 11 enums switch-statement swift

(当我准备并几乎写完问题时,重新阅读相应的语言指南部分为我解答了,但可能Q&A可能对其他人有用,所以我会发布它)

背景

请考虑以下enum情况,其中包含两种不同类型的关联值之一,Int或者String:

enum Foo {
    case bar(Int)
    case baz(Int)
    case bax(Int)
    case fox(String)
}
Run Code Online (Sandbox Code Playgroud)

switch语句中执行模式匹配时,我们可以构造复合案例,每个案例都包含几种可能的匹配模式(case如果任何模式匹配则进入分支):

func foo(_ foo: Foo) -> Int {
    switch foo {
        case .bar, .baz, .bax: return 42
        case .fox: return 0
    }
}
Run Code Online (Sandbox Code Playgroud)

就像非复合案例一样,复合案例也可能包含价值绑定:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 是否可以对复合案例使用单个公共值绑定,其中包含enum具有相同类型关联值的多个案例的复合?

例如,在上面的后面的值绑定示例中,某种方式将单个绑定功能用于复合中的公共类型关联值 case

// not valid
func foo(_ foo: Foo) -> Int {
    switch foo {
        case .bar, .baz, .bax, (let x): return x 
        case .fox: return 0
    }
}
Run Code Online (Sandbox Code Playgroud)

dfr*_*fri 6

不,这是不可能的;在上面的值绑定示例中,x必须在每个模式中都进行绑定,并且在复合情况下,这对于每个模式都必须分别适用。

引用语言指南-控制流 [ 强调我的 ]

复合案例还可以包括值绑定。复合案例的所有模式必须包含相同的值绑定集,并且每个绑定必须从复合案例的所有模式中获取相同类型的值。这样可以确保,无论复合案例的哪一部分匹配,案例主体中的代码始终可以访问绑定的值,并且该值始终具有相同的类型。

我尝试在上述复合示例中的其中一种模式中省略绑定,我们对此主题给出了不言自明的错误消息:

func foo(_ foo: Foo) -> Int {
    switch foo {
        case .bar(_), .baz(let x), .bax(let x): return x 
        case .fox: return 0
    }
}
Run Code Online (Sandbox Code Playgroud)
error: 'x' must be bound in every pattern
Run Code Online (Sandbox Code Playgroud)

即使我们不在后面x的正文中使用它,这仍然成立

func foo(_ foo: Foo) -> Int {
    switch foo {
        case .bar(_), .baz(let x), .bax(let x): return 0 
        case .fox: return 0
    }
} // same error
Run Code Online (Sandbox Code Playgroud)