Swiftコンパイラエラー:enumケースには、関連付けられた値として単一のタプルがありますが、ここにはいくつかのパターンがあります


12

Xcode 11.4ベータ3でプロジェクトをビルドすると、列挙型で次のSwiftコンパイラエラーが発生します。

列挙型のケースには、関連付けられた値として単一のタプルがありますが、ここにはいくつかのパターンがあり、暗黙的にパターンをタプルし、代わりにそれを一致させようとします

ソースコード:

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

Result以下のための関連する値を持つ一般的な列挙型である.error.value。この場合、関連する値はタプルです。

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

以前にこのエラーが表示されたことを思い出さないでください。検索しても結果は得られませんでした。何か案は?


1
私は質問を更新しました、それを省略して申し訳ありません
Eneko Alonso

結果ホイールを再発明する必要はありません。すでに存在しています。developer.apple.com/documentation/swift/result
マット

また、Xcode 11.4ベータ4(まだ)はありません。
マット

私の悪い、私はXcode 11.4ベータ3を意味しました。に関してはResult、私は同意しSwift.Resultます。しかし、それは問題とは何の関係もありません。
エネコアロンソ

1
私は完全に同意します、私は質問を片付けようとしているだけです。ここで良い点を挙げてください。これは、他の人が見つける正しいアプローチを文書化するチャンスです。
マット

回答:


14

関連付けられた値を追加のかっこで囲むことにより、タプルのように扱うことで、このエラーを抑制できることもわかりました。

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

1
それはいいです、私はそれが好きです、ありがとう。
エネコアロンソ

2
移動考えてみましょうlet:あなたは、バインドすべてに行くもののているかどうかをcase let .value( (staff, locations) ):してcase .value( let (staff, locations) ):、両方のコンパイル。お気に入りを選択してください!
ジェシー

1
スーパーマイナーですが、私はすべてを単一のletでバインドすることについての上記のコメントにスタイル的に同意しません。バインドされているものの左側にletを置くと、読みやすく、バインドされているものをすばやく理解できます。そうでなければ、letがバインドしているものを精神的に推定する必要があります。GoogleのSwift
ToddH

2
「Googleの」ガイドライン:/
Gee.E

9

わかりました。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):  
    //
}

解決

タプルからの値は、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)

たとえば、タプルタイプのオプションをオンにするときに括弧を省略すると、コンパイラエラーが発生します。

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

}


追加情報をありがとう、そしてリリースノートへのリンク。私は逃しました。
エネコアロンソ

0

よろしければif caseバージョンの回答も追加したいと思います。

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

そしてもちろん、大文字と小文字を区別しません:

if case let .value(staff, _) = result {
    // Do something
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.