Swift编译器错误:枚举案例有一个元组作为关联值,但是这里有几种模式


12

在Xcode 11.4 beta 3中构建一个项目,我在枚举中遇到了这个Swift Compiler错误:

枚举案例有一个元组作为关联值,但是这里有几种模式,隐式地将模式组合起来,然后尝试匹配

源代码:

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

Result是一个通用的枚举与相关联的值.error.value。在这种情况下,关联的值为tupple。

public enum Result<T> {
    case value(T)
    case error(Error)
}

不要回想起以前曾遇到过此错误,并且搜索该错误不会产生任何结果。有任何想法吗?


1
我更新了问题,很抱歉
忽略

无需重新发明结果轮;它已经存在。developer.apple.com/documentation/swift/result
马特·

另外,还没有Xcode 11.4 beta 4。
马特·

不好意思,我的意思是Xcode 11.4 beta3。关于Result,我同意,这是早于的旧代码Swift.Result。不过,这与问题无关。
Eneko Alonso

1
我完全同意,我只是想解决这个问题。您在这里提出了一个好要点,这是我们提供机会记录正确方法以供他人查找的机会。
马特·

Answers:


14

我发现您也可以通过将相关值更像元组来对待(通过将其包装在额外的一组括号中)来使此错误静音:

switch result {
case .error(let err):
    //
case .value((let staff, let locations)):  
    //
}

1
很好,我喜欢,谢谢。
Eneko Alonso

2
但是let,如果要绑定所有内容,请考虑移出:case let .value( (staff, locations) ):case .value( let (staff, locations) ):同时进行编译。选择你的最爱!
Jessy

1
超级未成年人,但我在风格上不同意上述关于通过一次绑定来绑定所有内容的评论。将束缚放在绑定的事物的左侧更容易阅读和快速理解绑定的事物。否则,您需要从心理上推断出let的绑定。Google的swift编码指南还建议不要使用单个层叠:google.github.io/swift/#pattern-matching
ToddH

2
“ Google的”指南:/
Gee.E

9

好,知道了。似乎enum与关联值(其中值类型为tupple)类似,无法再在这样的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):  
    //
}

来自tupple的值必须在Xcode 11.4(Swift 5.2)中手动提取:

// Works on Xcode 11.4
switch result {
case .error(let err):
    //
case .value(let tupple):  
    let (staff, locations) = tupple
    // 
}

那当然是一种解决方案。
马特·

3

这是一个已知问题: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
...

}

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

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

}


感谢您提供其他信息,并链接到发行说明。我错过了。
Eneko Alonso

0

如果可以的话,我也想为该if case版本添加答案。

if case let .value(staff, error) = result {
    // Do something
}

然后当然忽略大小写:

if case let .value(staff, _) = result {
    // Do something
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.