Lewati ke konten

Error Rust E0559: variant has no field named X (field varian tidak dikenal)

E0559 artinya: kamu sedang membuat nilai enum dengan Enum::Variant { field: value }, dan salah satu field yang kamu tulis tidak ada di varian itu. Ini versi enum dari E0560, yaitu kesalahan yang sama untuk struct. Biasanya penyebabnya nama field yang disingkat atau salah ketik, field milik varian lain, atau kurung kurawal pada varian yang seharusnya memakai tanda kurung. Perbaikannya hampir selalu cuma satu kata. (Halaman ini bagian dari Penjelasan error compiler Rust.)

error[E0559]: variant `Shape::Circle` has no field named `r`
--> src/main.rs:8:33
|
8 | let shape = Shape::Circle { r: 2.0 }; // ❌ field-nya bernama `radius`
| ^ `Shape::Circle` does not have this field
|
= note: available fields are: `radius`

Artinya: varian Shape::Circle tidak punya field bernama r, dan field yang tersedia hanya radius.

Ini program yang menghasilkan error tersebut:

#[derive(Debug)]
enum Shape {
Circle { radius: f64 },
Rectangle { width: f64, height: f64 },
}
fn main() {
let shape = Shape::Circle { r: 2.0 }; // ❌ field-nya bernama `radius`
println!("{:?}", shape);
}

Judul error-nya menyebut varian-nya (Shape::Circle) dan field yang kamu tulis (r). Tanda ^ menunjuk ke field itu di dalam kurung kurawal. Rust melihat definisi Circle { radius: f64 } dan tidak menemukan field bernama r.

Setiap varian sebuah enum punya daftar field sendiri. Shape::Circle punya radius, Shape::Rectangle punya width dan height. Mereka tidak berbagi field, walaupun berada di enum yang sama.

Di bawah tanda panah, rustc memberi salah satu petunjuk berikut. Baca dulu petunjuknya, biasanya jawabannya ada di situ:

  • note: available fields are: `radius` (field yang tersedia: …): tidak ada nama yang mirip. Ini field milik varian ini yang belum kamu isi.
  • help: a field with a similar name exists (ada field dengan nama mirip): salah ketik, seperti kye untuk key. rustc menunjukkan baris yang sudah dibetulkan.
  • help: `Message::Write` is a tuple variant, use the appropriate syntax (Message::Write adalah tuple variant, pakai sintaks yang sesuai): field varian itu tidak punya nama, jadi butuh ( ), bukan { }.
  • note: all struct fields are already assigned (semua field sudah diisi): kamu sudah mengisi semua field yang sebenarnya, dan yang satu ini kelebihan.

Ini seperti memesan pizza dan minta “pinggiran besar”, padahal di menu hanya ada pilihan “ukuran pinggiran”. Dapurnya paham maksudmu, tapi formulir pesanannya tidak punya kotak dengan nama itu.

Varian enum dengan field bernama, seperti Circle { radius: f64 }, bekerja seperti struct kecil di dalam enum. Saat kamu membuatnya, Rust memeriksa bahwa kamu memberikan tepat field-field miliknya: tidak ada yang kurang, tidak ada yang lebih, tidak ada yang salah eja. Lihat Enum bisa menyimpan data.

Ini paling penting saat nanti kamu memakai match pada enum itu. Cabang Shape::Circle { radius } => ... hanya bisa bekerja kalau setiap Circle benar-benar punya radius. Kalau Rust meloloskan Shape::Circle { r: 2.0 }, jaminan itu hilang. Dengan menangkap salah ketiknya saat compile, setiap Circle di programmu tetap lengkap.

Perbaikan 1: Pakai nama field varian yang sebenarnya

Section titled “Perbaikan 1: Pakai nama field varian yang sebenarnya”

Pilih ini kalau rustc menampilkan available fields are atau a field with a similar name exists. Pakai nama dari petunjuknya. Nama field peka huruf besar-kecil dan ditulis dalam snake_case, jadi Radius dan radius adalah nama yang berbeda.

Salah ketik mendapat petunjuk “similar name”:

error[E0559]: variant `Event::KeyPress` has no field named `kye`
--> src/main.rs:8:31
|
8 | let e = Event::KeyPress { kye: 'a' };
| ^^^ unknown field
|
help: a field with a similar name exists
|
8 - let e = Event::KeyPress { kye: 'a' };
8 + let e = Event::KeyPress { key: 'a' };
|

Artinya: Event::KeyPress tidak punya field kye (field tidak dikenal), tapi ada field dengan nama yang mirip, yaitu key.

Nama pendek seperti r terlalu berbeda dari radius untuk disarankan, jadi kamu mendapat daftar field-nya. Apa pun petunjuknya, tulis field yang didefinisikan oleh varian itu:

#[derive(Debug)]
enum Shape {
Circle { radius: f64 },
Rectangle { width: f64, height: f64 },
}
#[derive(Debug)]
enum Event {
Click { x: i32, y: i32 },
KeyPress { key: char },
}
fn main() {
let shapes = [
Shape::Circle { radius: 2.0 }, // ✅ nama field yang sebenarnya
Shape::Rectangle { width: 3.0, height: 4.0 },
];
for shape in &shapes {
println!("{:?}", shape);
}
let events = [Event::KeyPress { key: 'a' }, Event::Click { x: 10, y: 20 }];
println!("{:?}", events);
}

Output:

Circle { radius: 2.0 }
Rectangle { width: 3.0, height: 4.0 }
[KeyPress { key: 'a' }, Click { x: 10, y: 20 }]
▶ Coba sendiri

Hati-hati dengan field init shorthand (singkatan pengisian field). Shape::Circle { r } berarti Shape::Circle { r: r }, jadi hasilnya juga E0559. Kalau variabelmu bernama r, tulis field-nya lengkap: Shape::Circle { radius: r }. Atau ganti nama variabelnya menjadi radius dan tulis Shape::Circle { radius }.

Perbaikan 2: Pakai tanda kurung untuk tuple variant

Section titled “Perbaikan 2: Pakai tanda kurung untuk tuple variant”

Pilih ini kalau rustc bilang is a tuple variant, use the appropriate syntax. Varian seperti Write(String) punya field, tapi field-nya tidak bernama. Jadi nama apa pun yang kamu tulis di dalam kurung kurawal pasti salah:

error[E0559]: variant `Message::Write` has no field named `text`
--> src/main.rs:8:30
|
4 | Write(String),
| ----- `Message::Write` defined here
...
8 | let m = Message::Write { text: String::from("hi") };
| ^^^^ field does not exist
|
help: `Message::Write` is a tuple variant, use the appropriate syntax
|
8 - let m = Message::Write { text: String::from("hi") };
8 + let m = Message::Write(/* String */);
|

Artinya: field text tidak ada, karena Message::Write adalah tuple variant, dan rustc menyarankan sintaks dengan tanda kurung.

/* String */ di saran itu adalah tempat kosong: isi dengan nilaimu. Buat tuple variant dengan tanda kurung, dengan urutan yang sama seperti definisinya:

#[derive(Debug)]
enum Message {
Move { x: i32, y: i32 }, // field bernama: pakai { }
Write(String), // field tanpa nama: pakai ( )
Color(u8, u8, u8),
}
fn main() {
let messages = vec![
Message::Move { x: 1, y: 2 },
Message::Write(String::from("halo")), // ✅ tanda kurung
Message::Color(255, 128, 0),
];
for m in &messages {
match m {
Message::Move { x, y } => println!("pindah ke ({}, {})", x, y),
Message::Write(text) => println!("tulis: {}", text),
Message::Color(r, g, b) => println!("warna: {} {} {}", r, g, b),
}
}
}

Output:

pindah ke (1, 2)
tulis: halo
warna: 255 128 0
▶ Coba sendiri

Kalau kamu lebih suka field-nya punya nama, ubah definisinya menjadi Write { text: String }. Setelah itu Message::Write { text: ... } bisa dipakai. Kebalikannya, tanda kurung pada varian dengan field bernama seperti Shape::Circle(2.0), memberi error lain: E0533, “expected value, found struct variant” (yang diharapkan nilai, yang ditemukan struct variant).

Perbaikan 3: Pilih varian yang benar, atau ubah variannya

Section titled “Perbaikan 3: Pilih varian yang benar, atau ubah variannya”

Pilih ini kalau field yang kamu tulis memang ada, hanya saja di varian lain. Di sini radius milik Circle, bukan Square:

error[E0559]: variant `Shape::Square` has no field named `radius`
--> src/main.rs:8:29
|
8 | let s = Shape::Square { radius: 2.0 };
| ^^^^^^ `Shape::Square` does not have this field
|
= note: available fields are: `side`

Artinya: Shape::Square tidak punya field radius; field yang tersedia hanya side.

Tanyakan pada dirimu, mana yang kamu maksud. Kalau kamu ingin lingkaran, pakai Shape::Circle { radius: 2.0 }. Kalau kamu ingin persegi, pakai field-nya: Shape::Square { side: 2.0 }.

Kalau kamu melihat note: all struct fields are already assigned, variannya sudah lengkap dan field-mu kelebihan. Hapus field itu, atau kalau kodemu memang membutuhkannya, tambahkan ke definisi variannya:

#[derive(Debug)]
enum Shape {
Circle { radius: f64 },
Square { side: f64 },
}
#[derive(Debug)]
enum Message {
Move { x: i32, y: i32, z: i32 }, // `z` ditambahkan, karena kodenya membutuhkannya
}
fn main() {
let a = Shape::Circle { radius: 2.0 }; // lingkaran punya jari-jari
let b = Shape::Square { side: 2.0 }; // persegi punya sisi
println!("{:?} dan {:?}", a, b);
let m = Message::Move { x: 1, y: 2, z: 3 };
println!("{:?}", m);
}

Output:

Circle { radius: 2.0 } dan Square { side: 2.0 }
Move { x: 1, y: 2, z: 3 }
▶ Coba sendiri

Begitu kamu menambahkan field ke sebuah varian, setiap tempat yang membuat varian itu juga harus mengisinya. rustc menunjuk setiap tempat itu dengan E0063, “missing field” (field belum diisi).

Method constructor dengan Self::. Di dalam impl Shape, menulis fn circle(r: f64) -> Shape { Self::Circle { r } } memberi E0559 untuk r, karena shorthand tadi. Perbaikannya: Self::Circle { radius: r }. Lihat Enum juga bisa punya method.

Setelah mengganti nama field. Kamu mengganti Circle { r } menjadi Circle { radius } di enum, dan sekarang setiap Shape::Circle { r: ... } yang lama memberi E0559 dengan available fields are: `radius`. Cari nama lamanya di seluruh proyek dan perbarui satu per satu.

Di dalam pattern match. Menulis nama field yang salah di dalam pattern, seperti Shape::Circle { r } => ..., adalah kesalahan yang sama, tapi rustc memakai kode lain: E0026, “variant Shape::Circle does not have a field named r”, dengan help: `Shape::Circle` has a field named `radius`, ditambah E0027 “pattern does not mention field radius” (pattern tidak menyebut field radius). Perbaikannya: Shape::Circle { radius } => ..., atau Shape::Circle { radius: r } => ... kalau kamu ingin tetap memakai nama pendeknya. Lihat Pattern matching.

Kuis singkat

1. Untuk enum Message { Write(String) }, Message::Write { text: s } harus diubah menjadi apa?

2. Kamu punya let r = 2.0; lalu menulis Shape::Circle { r }, padahal field-nya bernama radius. Bagaimana memperbaikinya?

3. Shape::Square { radius: 2.0 } memberi E0559, dan catatannya hanya menyebut side. Apa yang terjadi?

Skor: 0 / 3