Swift Compiler Error: enum case 有一个单独的元组作为关联值,但这里有几种模式

Ene*_*nso 17 swift

在 Xcode 11.4 beta 3 中构建项目,我在枚举上收到此 Swift 编译器错误:

枚举案例有一个单独的元组作为关联值,但这里有几个模式,隐式地对模式进行元组化并尝试与之匹配

源代码:

switch result {
case .error(let err):
    //
case .value(let staff, let locations):  // <-- error on this line
    //
}
Run Code Online (Sandbox Code Playgroud)

Result是一个具有关联值.error和的通用枚举.value。在这种情况下,关联的值是一个元组。

public enum Result<T> {
    case value(T)
    case error(Error)
}
Run Code Online (Sandbox Code Playgroud)

不记得以前看到过这个错误,搜索它没有产生任何结果。有任何想法吗?

Wer*_*nzy 20

我发现您还可以通过将关联值更像是一个元组来将其包装在一组额外的括号中来消除此错误:

switch result {
case .error(let err):
    //
case .value((let staff, let locations)):  
    //
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您要绑定所有内容,请考虑将 `let` 移出:`case let .value( (staff,locations) ):` 和 `case .value( let (staff,locations) ):` 都可以编译。选择你最喜欢的! (3认同)
  • 超级小,但我在风格上不同意上面关于用单个 let 绑定所有内容的评论。将 let 放在被绑定的事物的左侧更容易阅读并快速理解所绑定的事物。否则,您需要在心里推断 let 的绑定内容。Google 的 swift 编码指南也建议不要使用单个级联 let:https://google.github.io/swift/#pattern-matching (2认同)
  • “Google”指南:/ (2认同)

Ene*_*nso 18

好的,想通了。似乎enum关联值,其中值类型是一个元组,不能再匹配这样的switch语句:

// Works on Xcode 11.3.1, yields error on 11.4 (Swift 5.2)
switch result {
case .error(let err):
    //
case .value(let staff, let locations):  
    //
}
Run Code Online (Sandbox Code Playgroud)

解决方案

必须在 Xcode 11.4 (Swift 5.2) 中手动提取元组中的值:

// Works on Xcode 11.4
switch result {
case .error(let err):
    //
case .value(let tuple):  
    let (staff, locations) = tuple
    // 
}
Run Code Online (Sandbox Code Playgroud)


小智 5

这是一个已知问题:https : //developer.apple.com/documentation/xcode_release_notes/xcode_11_4_release_notes

升级到 Xcode 11.4 时,依赖编译器自动对模式进行元组化的代码可能会导致编译器错误,即使之前编译过的代码也是如此。(58425942)

例如,在打开元组类型的 Optional 时省略括号会导致编译器错误:

switch x { // error: switch must be exhaustive
case .some((let a, let b), let c): // warning: the enum case has a
     // single tuple as an associated value, but there are several
     // patterns here, implicitly tupling the patterns and trying
     // to match that instead
...
Run Code Online (Sandbox Code Playgroud)

}

解决方法:添加额外的括号以显式元组模式:

switch x {
case .some(((let a, let b), let c)): // Notice the extra pair of parentheses.
...
Run Code Online (Sandbox Code Playgroud)

}