Swift Compiler Error: Enum case memiliki satu tuple sebagai nilai terkait, tetapi ada beberapa pola di sini

12

Membangun proyek di Xcode 11.4 beta 3, saya mendapatkan kesalahan Swift Compiler ini pada enum:

Enum case memiliki satu tuple sebagai nilai terkait, tetapi ada beberapa pola di sini, secara implisit menggandakan pola dan mencoba untuk mencocokkannya sebagai gantinya

Kode sumber:

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

Resultadalah enum umum dengan nilai terkait untuk .errordan .value. Dalam hal ini, nilai yang terkait adalah tupple.

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

Jangan ingat melihat kesalahan ini sebelumnya, dan mencarinya tidak membuahkan hasil. Ada ide?

Eneko Alonso
sumber
1
Saya memperbarui pertanyaan, maaf karena meninggalkan itu
Eneko Alonso
Tidak perlu menemukan kembali roda Hasil; sudah ada. developer.apple.com/documentation/swift/result
matt
Juga, belum ada Xcode 11.4 beta 4 (belum).
matt
Buruk saya, saya maksud Xcode 11.4 beta 3. Sehubungan dengan Result, saya setuju, itu kode lama yang ada sebelum Swift.Result. Tapi itu tidak ada hubungannya dengan masalah ini.
Eneko Alonso
1
Saya sepenuhnya setuju, saya hanya mencoba untuk membersihkan pertanyaan. Anda mengangkat poin yang baik di sini dan ini adalah kesempatan kami untuk mendokumentasikan pendekatan yang benar untuk ditemukan orang lain.
matt

Jawaban:

14

Saya menemukan Anda juga dapat membungkam kesalahan ini dengan memperlakukan nilai yang terkait lebih seperti tuple dengan membungkusnya dalam set kurung tambahan:

switch result {
case .error(let err):
    //
case .value((let staff, let locations)):  
    //
}
Wernzy
sumber
1
Itu bagus, saya suka, terima kasih.
Eneko Alonso
2
Pertimbangkan untuk pindah letjika Anda akan mengikat semuanya: case let .value( (staff, locations) ):dan case .value( let (staff, locations) ):keduanya kompilasi. Pilih fave Anda!
Jessy
1
Super minor tapi saya gaya tidak setuju dengan komentar di atas tentang mengikat semuanya dengan satu let. Memiliki hak di sebelah kiri hal yang terikat lebih mudah dibaca dan dengan cepat memahami hal-hal yang terikat. Kalau tidak, Anda perlu memperkirakan mental apa yang mengikat mengikat. Pedoman pengkodean Google untuk swift juga menyarankan agar cascading tunggal tidak membiarkan: google.github.io/swift/#pattern-matching
ToddH
2
Pedoman "Google": /
Gee.E
9

Oke, cari tahu. Sepertinya enumdengan nilai terkait, di mana tipe nilai adalah sebuah tupple, tidak bisa lagi dicocokkan pada pernyataan switch seperti itu:

// 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):  
    //
}

Larutan

Nilai dari tupple harus diekstraksi secara manual dalam 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
    // 
}
Eneko Alonso
sumber
Itu tentu salah satu solusinya.
matt
3

Ini adalah masalah yang diketahui: https://developer.apple.com/documentation/xcode_release_notes/xcode_11_4_release_notes

Kode yang bergantung pada kompiler secara otomatis tupling pola dapat menyebabkan kesalahan kompiler ketika memutakhirkan ke Xcode 11.4, meskipun kode dikompilasi sebelumnya. (58425942)

Sebagai contoh, meninggalkan tanda kurung ketika menyalakan Opsional dari jenis tuple menyebabkan kesalahan kompiler:

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

}

Penanganan masalah : Tambahkan kurung tambahan untuk secara eksplisit tuple pola:

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

}

bolinhalouise
sumber
Terima kasih atas info tambahan, dan tautan ke catatan rilis. Saya melewatkan itu.
Eneko Alonso
0

Jika boleh, saya ingin menambahkan jawaban untuk if caseversi itu juga.

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

dan tentu saja mengabaikan kasus:

if case let .value(staff, _) = result {
    // Do something
}
Paul Peelen
sumber