Lewati ke konten

Error Rust E0533: expected unit struct, unit variant or constant, found struct variant

E0533 artinya: kamu menulis sebuah nama seperti Shape::Circle begitu saja, padahal di tempat itu namanya saja tidak cukup. Paling sering, ini varian enum dengan field bernama (Circle { radius: f64 }) yang ditulis tanpa { }-nya, entah di arm match atau saat membuat nilai. Lebih jarang, ini fungsi atau method yang ditulis di tempat yang hanya boleh diisi nilai tetap. Keduanya cepat diperbaiki begitu kamu tahu apa yang diminta rustc. (Halaman ini bagian dari Penjelasan error compiler Rust.)

error[E0533]: expected unit struct, unit variant or constant, found struct variant `Shape::Circle`
--> src/main.rs:8:9
|
8 | Shape::Circle => "lingkaran", // ❌ `Circle` punya field
| ^^^^^^^^^^^^^ not a unit struct, unit variant or constant
|
help: the struct variant's field is being ignored
|
8 | Shape::Circle { radius: _ } => "lingkaran", // ❌ `Circle` punya field
| +++++++++++++

Artinya: rustc mengharapkan unit struct, unit variant, atau konstanta, tapi yang ditemukan adalah varian struct Shape::Circle. Saran help:-nya menambahkan field-nya ke pattern dan mengabaikannya dengan _.

Ini program yang menghasilkan error tersebut:

enum Shape {
Circle { radius: f64 },
Square { side: f64 },
}
fn name(shape: &Shape) -> &'static str {
match shape {
Shape::Circle => "lingkaran", // ❌ `Circle` punya field
Shape::Square { .. } => "persegi",
}
}
fn main() {
println!("{}", name(&Shape::Square { side: 2.0 }));
}

Tanda ^^^ menunjuk ke Shape::Circle, dan judul error-nya menjelaskan apa yang boleh ada di sana: sebuah pattern (pola) yang hanya berupa nama harus salah satu dari tiga hal ini:

  • unit struct, seperti struct Empty;
  • unit variant, varian tanpa data, seperti Shape::Empty atau None
  • konstanta, seperti const MAX: u32 = 100;

Shape::Circle bukan salah satunya. Ia adalah varian struct: ia membawa sebuah radius. Shape::Circle saja akan cocok dengan “sebuah lingkaran”, tapi tidak mengatakan apa pun tentang field-nya, dan Rust ingin bentuk pattern-nya sama dengan bentuk variannya. Baris help: menunjukkan perbaikannya: tambahkan kurung kurawalnya.

Jenis E0533 yang kedua berbunyi expected value, found struct variant (mengharapkan nilai, tapi menemukan varian struct). Kebingungannya sama, tapi terjadi saat membuat nilai, biasanya ditulis dengan tanda kurung seperti Shape::Circle(2.0).

Ibaratnya formulir paket dengan kotak bertuliskan “Ukuran: S, M, atau L”, lalu kamu menulis “Khusus”. Khusus memang pilihan yang ada, tapi ukurannya harus diisi di sebelahnya.

Varian enum punya tiga bentuk, dan masing-masing ditulis dengan caranya sendiri, baik saat kamu membuatnya maupun saat kamu mencocokkannya (lihat Enum bisa menyimpan data):

Varian Cara membuat Cara mencocokkan
Unit: Empty Shape::Empty Shape::Empty
Tuple: Point(f64, f64) Shape::Point(1.0, 2.0) Shape::Point(x, y) atau Shape::Point(..)
Struct: Circle { radius: f64 } Shape::Circle { radius: 2.0 } Shape::Circle { radius } atau Shape::Circle { .. }

Dengan bentuk yang ketat, sebuah pattern selalu terlihat seperti hal yang dicocokkannya, jadi kamu bisa membaca sebuah match dan langsung tahu data apa yang dimiliki setiap arm. Ini juga berarti, saat sebuah varian berubah bentuk, misalnya saat Empty mendapat field, setiap tempat yang memakai bentuk lama akan ditandai, bukan diam-diam melakukan hal yang salah.

Perbaikan 1: Tambahkan { .. } atau field-nya ke pattern

Section titled “Perbaikan 1: Tambahkan { .. } atau field-nya ke pattern”

Pilih ini kalau error-nya menunjuk ke arm match, if let, atau matches! dan bilang found struct variant. Tulis { .. } kalau kamu tidak butuh field-nya, atau sebut namanya kalau kamu butuh. Saran rustc { radius: _ } juga bisa, dan { .. } adalah cara yang lebih pendek untuk mengatakan hal yang sama.

enum Shape {
Circle { radius: f64 },
Square { side: f64 },
Empty,
}
fn name(shape: &Shape) -> &'static str {
match shape {
Shape::Circle { .. } => "lingkaran", // ✅ "sebuah lingkaran, berapa pun radiusnya"
Shape::Square { .. } => "persegi",
Shape::Empty => "kosong", // unit variant: tidak perlu kurung kurawal
}
}
fn area(shape: &Shape) -> f64 {
match shape {
Shape::Circle { radius } => 3.14 * radius * radius, // ✅ field disebut karena kita butuh
Shape::Square { side } => side * side,
Shape::Empty => 0.0,
}
}
fn main() {
let shapes = [Shape::Circle { radius: 1.0 }, Shape::Square { side: 3.0 }, Shape::Empty];
for shape in &shapes {
println!("{}: {:.2}", name(shape), area(shape));
}
let circles = shapes.iter().filter(|s| matches!(s, Shape::Circle { .. })).count();
println!("{} lingkaran", circles);
}

Output:

lingkaran: 3.14
persegi: 9.00
kosong: 0.00
1 lingkaran
▶ Coba sendiri

{ .. } bisa dipakai untuk setiap varian struct, berapa pun jumlah field-nya. Untuk varian tuple, ide yang sama ditulis (..). Lihat Mengabaikan bagian dengan _ dan ...

Perbaikan 2: Buat nilainya dengan kurung kurawal dan nama field

Section titled “Perbaikan 2: Buat nilainya dengan kurung kurawal dan nama field”

Pilih ini kalau pesannya bilang expected value, found struct variant. Kamu membuat varian struct seolah-olah itu varian tuple (atau tanpa field sama sekali):

error[E0533]: expected value, found struct variant `Shape::Circle`
--> src/main.rs:8:17
|
8 | let shape = Shape::Circle(2.0); // ❌ `Circle` punya field bernama
| ^^^^^^^^^^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
8 - let shape = Shape::Circle(2.0); // ❌ `Circle` punya field bernama
8 + let shape = Shape::Circle { radius: /* value */ }; // ❌ `Circle` punya field bernama
|

Artinya: di sini rustc mengharapkan sebuah nilai, tapi Shape::Circle adalah varian struct, jadi tidak bisa dipanggil seperti fungsi. rustc menyarankan menulisnya dengan kurung kurawal dan nama field-nya.

Program di baliknya:

#[derive(Debug)]
enum Shape {
Circle { radius: f64 },
Square { side: f64 },
}
fn main() {
let shape = Shape::Circle(2.0); // ❌ `Circle` punya field bernama
println!("{:?}", shape);
}

/* value */ di saran itu adalah tempat untuk nilaimu. Field dari varian struct diisi berdasarkan nama, di dalam kurung kurawal:

#[derive(Debug)]
enum Shape {
Circle { radius: f64 },
Square { side: f64 },
}
impl Shape {
// constructor singkat, kalau kamu ingin menulis `Shape::circle(2.0)`
fn circle(radius: f64) -> Shape {
Shape::Circle { radius }
}
}
fn main() {
let a = Shape::Circle { radius: 2.0 }; // ✅ kurung kurawal dan nama field
let b = Shape::Square { side: 1.5 };
let c = Shape::circle(0.5);
println!("{:?}", a);
println!("{:?}", b);
println!("{:?}", c);
}

Output:

Circle { radius: 2.0 }
Square { side: 1.5 }
Circle { radius: 0.5 }
▶ Coba sendiri

Kalau kamu lebih suka menulis Shape::Circle(2.0), ubah definisinya menjadi varian tuple: Circle(f64). Itu pilihan yang bagus untuk satu field yang sudah jelas; field bernama lebih jelas kalau jumlahnya beberapa.

Perbaikan 3: Pakai konstanta atau match guard, bukan fungsi

Section titled “Perbaikan 3: Pakai konstanta atau match guard, bukan fungsi”

Pilih ini kalau pesannya bilang found associated function (menemukan associated function). Ini juga muncul untuk method, seperti String::len. Sebuah pattern harus berupa nilai yang sudah diketahui saat kompilasi. Pemanggilan fungsi tidak memenuhi syarat itu, jadi nama fungsi tidak bisa dipakai sebagai pattern:

error[E0533]: expected unit struct, unit variant or constant, found associated function `Limits::max_users`
--> src/main.rs:12:9
|
12 | Limits::max_users => "penuh", // ❌ fungsi tidak bisa jadi pattern
| ^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant

Artinya: di posisi pattern, rustc menemukan associated function Limits::max_users, padahal yang boleh hanya unit struct, unit variant, atau konstanta.

Program di baliknya:

struct Limits;
impl Limits {
fn max_users() -> u32 {
100
}
}
fn status(users: u32) -> &'static str {
match users {
0 => "kosong",
Limits::max_users => "penuh", // ❌ fungsi tidak bisa jadi pattern
_ => "masih ada tempat",
}
}
fn main() {
println!("{}", status(100));
}

Kalau nilainya tidak pernah berubah, jadikan const. Konstanta bisa jadi pattern. Kalau nilainya harus dihitung, pertahankan fungsinya dan bandingkan di dalam match guard dengan if:

struct Limits;
impl Limits {
const MAX_USERS: u32 = 100; // konstanta bisa dipakai sebagai pattern
fn max_rooms(premium: bool) -> u32 {
if premium { 20 } else { 5 }
}
}
fn status(users: u32) -> &'static str {
match users {
0 => "kosong",
Limits::MAX_USERS => "penuh", // ✅ sebuah konstanta
_ => "masih ada tempat",
}
}
fn rooms_status(rooms: u32, premium: bool) -> &'static str {
match rooms {
n if n >= Limits::max_rooms(premium) => "ruangan sudah maksimal", // ✅ panggil di guard
_ => "kamu bisa menambah ruangan",
}
}
fn main() {
println!("{}", status(0));
println!("{}", status(100));
println!("{}", status(42));
println!("{}", rooms_status(5, false));
println!("{}", rooms_status(5, true));
}

Output:

kosong
penuh
masih ada tempat
ruangan sudah maksimal
kamu bisa menambah ruangan
▶ Coba sendiri

Match guard dijelaskan di Match guard: menambahkan if.

Setelah unit variant mendapat field. Status::Done dulunya unit variant, lalu kamu mengubahnya menjadi Done { at: u64 }. Sekarang setiap arm Status::Done => dan setiap let s = Status::Done; memberi E0533. Perbaikannya: Status::Done { .. } => di pattern, dan Status::Done { at: 0 } (dengan nilai yang sebenarnya) di tempat kamu membuatnya.

Terbiasa dengan bahasa lain. Di Java atau TypeScript, kamu mungkin menulis case Circle: untuk memeriksa jenis sebuah nilai saja. Di Rust, tulis Shape::Circle { .. } =>, atau matches!(shape, Shape::Circle { .. }) untuk mendapat bool dengan cepat.

Versi varian tuple. Untuk varian tuple seperti Circle(f64), arm Shape::Circle => tanpa apa-apa memberi kode lain, E0532, dengan judul yang sama “expected unit struct, unit variant or constant, found tuple variant Shape::Circle”. Perbaikannya Shape::Circle(_) atau Shape::Circle(..). Dan tanda kurung pada varian struct di dalam pattern, seperti Shape::Circle(r) => untuk Circle { radius: f64 }, memberi E0164, “expected tuple struct or tuple variant, found struct variant” (mengharapkan tuple struct atau varian tuple, tapi menemukan varian struct). Perbaikannya: Shape::Circle { radius: r } =>.

Kuis singkat

1. Untuk enum Shape { Circle { radius: f64 } }, arm match mana yang bisa dikompilasi?

2. let s = Shape::Circle(2.0); memberi "expected value, found struct variant". Apa perbaikannya?

3. Mana yang bisa dipakai sendirian sebagai pattern di match?

Skor: 0 / 3