复合开关情况:对于具有相同关联值类型的复合枚举情况,我们是否可以拥有单个通用值绑定?

17

(当我准备并快要完成问题的撰写时,重新阅读了适当的语言指南部分,这回答了我的问题,但可能该问答对其他人有用,因此我仍然会发布它)

背景

考虑以下enum,具有具有两种不同类型的关联值,即IntString的情况:

enum Foo {
    case bar(Int)
    case baz(Int)
    case bax(Int)
    case fox(String)
}
switch 语句中进行模式匹配时,我们可以构建复合 case,每个 case 覆盖多个可能的匹配模式(如果任何一个模式匹配,则进入 case 分支):
func foo(_ foo: Foo) -> Int {
    switch foo {
        case .bar, .baz, .bax: return 42
        case .fox: return 0
    }
}

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

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
    }
}

问题

  • 是否可以使用单个通用值绑定来处理复合情况,其中涵盖了具有相同关联值类型的几个enum案例组合?

例如,在上面的后续值绑定示例中,是否有一种方法可以使用单个绑定功能来处理复合case中的共同类型关联值

// not valid
func foo(_ foo: Foo) -> Int {
    switch foo {
        case .bar, .baz, .bax, (let x): return x 
        case .fox: return 0
    }
}
1个回答

9
不,这是不可能的;在上述值绑定示例中,x必须在每个模式中都被绑定,并且对于复合案例中的每个模式都必须分别满足此条件。
引用语言指南-控制流 [我强调]:

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

如果我们尝试省略复合示例中一个模式中的绑定,我们将收到一个非常自说明的错误消息:
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

即使在接下来的正文中不使用x,这个规则仍然适用。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接