Lewati ke konten

Error Rust E0560: struct has no field named X (field tidak dikenal)

E0560 artinya: kamu sedang membuat struct dengan Name { field: value }, dan salah satu field yang kamu tulis tidak ada di struct itu. Biasanya penyebabnya salah ketik, field yang sudah diganti namanya, atau field milik struct lain. rustc sering langsung memberi tahu nama yang kamu maksud, jadi ini salah satu error yang paling cepat diperbaiki. (Halaman ini bagian dari Penjelasan error compiler Rust.)

error[E0560]: struct `User` has no field named `nmae`
--> src/main.rs:9:9
|
9 | nmae: String::from("Ferris"), // ❌ salah ketik: field-nya bernama `name`
| ^^^^ unknown field
|
help: a field with a similar name exists
|
9 - nmae: String::from("Ferris"), // ❌ salah ketik: field-nya bernama `name`
9 + name: String::from("Ferris"), // ❌ salah ketik: field-nya bernama `name`
|

Artinya: struct User tidak punya field bernama nmae (field tidak dikenal), tapi ada field dengan nama yang mirip.

Ini program yang menghasilkan error tersebut:

struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let user = User {
nmae: String::from("Ferris"), // ❌ salah ketik: field-nya bernama `name`
email: String::from("[email protected]"),
active: true,
};
println!("{}", user.email);
}

Judul error-nya menyebut struct-nya (User) dan field yang kamu tulis (nmae). Tanda ^^^^ menunjuk ke field itu di dalam blok User { ... }. Rust membandingkannya dengan daftar field di struct User dan tidak menemukan yang cocok.

Di bawah tanda panah, kamu akan mendapat salah satu dari tiga petunjuk. Masing-masing punya arti yang berbeda:

  • help: a field with a similar name exists (ada field dengan nama mirip): salah ketik. rustc menunjukkan baris dengan nama yang benar.
  • note: available fields are: `username` (field yang tersedia: …): tidak ada nama yang mirip. Ini daftar field yang belum kamu isi.
  • note: all struct fields are already assigned (semua field struct sudah diisi): kamu sudah mengisi semua field yang sebenarnya, dan yang satu ini kelebihan.

Perhatikan bahwa rustc tidak sekalian protes bahwa name belum diisi. Betulkan salah ketiknya, dan kedua masalah itu hilang sekaligus.

Ini seperti mengisi formulir kertas dan menulis nomor teleponmu di kotak berlabel “Faks”. Formulirnya tidak punya kotak seperti itu, jadi petugasnya mengembalikan formulirmu.

Field sebuah struct sudah pasti begitu kamu menulis struct User { ... }. Setiap kali kamu membuat User, Rust memeriksa bahwa kamu memberikan tepat field-field itu: tidak ada yang kurang, tidak ada yang lebih, tidak ada yang salah eja. Lihat Mendefinisikan dan membuat struct.

Ini menangkap bug sungguhan. Di JavaScript, { nmae: "Ferris" } diam-diam membuat objek dengan key yang salah, dan user.name menjadi undefined di suatu tempat jauh belakangan. Di Rust, salah ketik itu tidak bisa lolos dari compiler, jadi setiap User di programmu benar-benar punya name.

Pilih ini kalau kamu melihat a field with a similar name exists. Pakai nama dari baris help:. Nama field peka huruf besar-kecil, dan Rust memakai snake_case, jadi userName dan user_name adalah nama yang berbeda.

Hati-hati juga dengan field init shorthand (singkatan pengisian field): User { nmae, email } berarti User { nmae: nmae, email: email }, jadi nama variabel-nya harus sama dengan nama field-nya. Ganti nama variabelnya, atau tulis field-nya lengkap: User { name: nmae, email }.

struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let user = User {
name: String::from("Ferris"), // ✅ nama field yang sebenarnya
email: String::from("[email protected]"),
active: true,
};
println!("{} ({}) aktif: {}", user.name, user.email, user.active);
// shorthand: nama variabelnya sama dengan nama field-nya
let name = String::from("Ada");
let email = String::from("[email protected]");
let other = User { name, email, active: false };
println!("{} ({}) aktif: {}", other.name, other.email, other.active);
}

Output:

Ferris ([email protected]) aktif: true
Ada ([email protected]) aktif: false
▶ Coba sendiri

Perbaikan 2: Pakai nama baru field-nya, atau tambahkan field-nya

Section titled “Perbaikan 2: Pakai nama baru field-nya, atau tambahkan field-nya”

Pilih ini kalau tidak ada petunjuk “similar name”. Sering kali struct-nya sudah berubah: seseorang mengganti nama name menjadi username, atau sebuah field dihapus, tapi kode ini masih memakai yang lama. rustc menampilkan field yang tersisa:

error[E0560]: struct `User` has no field named `name`
--> src/main.rs:8:9
|
8 | name: String::from("Ferris"),
| ^^^^ `User` does not have this field
|
= note: available fields are: `username`

Di sini rustc bilang User tidak punya field ini, dan field yang tersedia hanya username.

Kamu punya dua pilihan yang sama-sama masuk akal. Kalau struct-nya yang benar, pakai nama field-nya yang sekarang. Kalau kodemu yang benar dan struct-nya memang butuh field itu, tambahkan ke definisi struct-nya. Di sini Config memberi all struct fields are already assigned untuk debug, dan perbaikannya adalah menambahkan debug ke struct-nya:

struct User {
username: String, // dulu bernama `name`: pakai nama barunya
email: String,
}
struct Config {
port: u16,
host: String,
debug: bool, // ditambahkan ke struct, karena kodenya membutuhkannya
}
fn main() {
let user = User {
username: String::from("ferris"),
email: String::from("[email protected]"),
};
println!("{} ({})", user.username, user.email);
let config = Config {
port: 8080,
host: String::from("localhost"),
debug: true,
};
println!("{}:{} debug={}", config.host, config.port, config.debug);
}

Output:

localhost:8080 debug=true
▶ Coba sendiri

Kalau struct-nya berasal dari crate yang baru saja kamu perbarui, mungkin field-nya diganti namanya di versi baru. Periksa struct itu di docs.rs (bahasa Inggris) untuk versi tersebut, atau changelog crate-nya. Begitu kamu menambahkan field ke struct buatanmu sendiri, setiap tempat yang membuat struct itu juga harus mengisinya. rustc akan menunjuk setiap tempat itu dengan E0063 (lihat di bawah).

Pilih ini kalau field yang kamu tulis memang ada, hanya saja di struct lain. Dengan dua struct yang mirip, seperti Product yang punya title dan Customer yang punya name, gampang sekali tertukar:

error[E0560]: struct `Product` has no field named `name`
--> src/main.rs:13:9
|
13 | name: String::from("Keyboard"),
| ^^^^ `Product` does not have this field
|
= note: available fields are: `title`

Lihat catatan available fields. Kalau isinya field yang tidak kamu duga, berarti kamu sedang membuat struct yang salah. Pakai nama struct yang benar, atau nama field dari struct yang kamu maksud:

struct Product {
title: String,
price: u32, // dalam sen
}
struct Customer {
name: String,
email: String,
}
fn main() {
let keyboard = Product {
title: String::from("Keyboard"), // produk punya `title`
price: 4900,
};
let buyer = Customer {
name: String::from("Ana"), // pelanggan punya `name`
email: String::from("[email protected]"),
};
println!("{} membeli {} seharga {} sen", buyer.name, keyboard.title, keyboard.price);
println!("Struk dikirim ke {}", buyer.email);
}

Output:

Ana membeli Keyboard seharga 4900 sen
Struk dikirim ke [email protected]
▶ Coba sendiri

Perbaikan 4: Pakai tanda kurung untuk tuple struct

Section titled “Perbaikan 4: Pakai tanda kurung untuk tuple struct”

Pilih ini kalau struct-nya adalah tuple struct, seperti struct Point(i32, i32);. Field-nya tidak punya nama, jadi Point { x: 1, y: 2 } menghasilkan E0560 untuk x dan y, dengan help: `Point` is a tuple struct, use the appropriate syntax (Point adalah tuple struct, pakai sintaks yang sesuai) dan saran Point(/* i32 */, /* i32 */). Buat dengan tanda kurung, Point(1, 2), dan baca dengan .0 dan .1. Kalau kamu lebih suka pakai nama, ubah definisinya menjadi struct Point { x: i32, y: i32 }. Lihat Kapan memakai tuple dan kapan memakai struct.

Kembaran E0560 adalah E0063: field yang ada di struct, tapi tidak kamu isi. Rust tidak pernah mengisi field untukmu, jadi setiap field butuh nilai:

error[E0063]: missing field `active` in initializer of `User`
--> src/main.rs:8:16
|
8 | let user = User {
| ^^^^ missing `active`

Artinya: field active belum diisi saat membuat User.

Kalau ada beberapa field yang belum diisi, semuanya disebutkan: missing fields `active`, `email` and `login_count` in initializer of `User`. Perbaikannya: beri nilai pada setiap field. Kalau banyak field punya nilai default yang masuk akal, derive Default dan pakai struct update syntax .. untuk mengisi sisanya:

#[derive(Debug, Default)]
struct Settings {
volume: u8,
dark_mode: bool,
language: String,
}
fn main() {
// semua field ditulis lengkap
let full = Settings { volume: 80, dark_mode: false, language: String::from("en") };
// hanya field yang kamu pedulikan, sisanya dari Default
let quick = Settings { dark_mode: true, ..Default::default() };
// salin sisanya dari nilai lain
let louder = Settings { volume: 100, ..full };
println!("{:?}", quick);
println!("{:?}", louder);
}

Output:

Settings { volume: 0, dark_mode: true, language: "" }
Settings { volume: 100, dark_mode: false, language: "en" }
▶ Coba sendiri

Nilai default untuk angka adalah 0, untuk bool adalah false, dan untuk String adalah string kosong. Kalau kamu ingin nilai default lain, tulis sendiri impl Default for Settings. Lihat Default: nilai awal yang masuk akal.

Di dalam update syntax ... Settings { dark: true, ..defaults } juga menghasilkan E0560. Di sini catatannya menyebutkan semua field (available fields are: `volume`, `dark_mode`, `language`), dan mungkin tidak ada petunjuk “similar name” kalau namanya terlalu berbeda. Perbaikannya: dark_mode: true.

Varian enum dengan field bernama. Untuk enum Shape { Circle { radius: f64 } }, menulis Shape::Circle { r: 2.0 } adalah kesalahan yang sama, tapi rustc memakai kode lain: E0559, variant `Shape::Circle` has no field named `r`, dengan catatan available fields dan petunjuk salah ketik yang sama. Perbaikannya: Shape::Circle { radius: 2.0 }. Lihat Enum bisa menyimpan data.

Struct dari modul lain. Kalau field-nya ada tapi tidak pub, kamu malah mendapat E0451, “field balance of struct Account is private” (field balance pada struct Account bersifat private). Perbaikannya: pakai constructor dari modul itu, seperti Account::new(...). Lihat Semuanya private secara default.

Kuis singkat

1. rustc bilang note: all struct fields are already assigned. Apa artinya?

2. Kamu punya let nmae = ...; lalu menulis User { nmae, email }. Bagaimana memperbaikinya?

3. Error apa yang muncul kalau kamu tidak mengisi sebuah field, misalnya User { name, email } tanpa active?

Skor: 0 / 3