Error Rust E0532: expected unit struct, unit variant or constant, found tuple variant
E0532 artinya: bentuk pattern-mu tidak cocok dengan bentuk hal yang kamu sebut. Contoh klasiknya adalah cabang match seperti Shape::Circle => untuk varian yang menyimpan data, Circle(f64). Rust ingin ada tanda kurungnya: Shape::Circle(_). Kesalahan kebalikannya mendapat kode yang sama, dengan kalimat lain, “expected tuple struct or tuple variant”: tanda kurung pada sesuatu yang tidak punya data dalam tanda kurung, seperti Status::Active(). Keduanya bisa diperbaiki dalam satu baris. (Halaman ini bagian dari Penjelasan error compiler Rust.)
Pesan error-nya
Section titled “Pesan error-nya”error[E0532]: expected unit struct, unit variant or constant, found tuple variant `Shape::Circle` --> src/main.rs:8:9 |2 | Circle(f64), | ----------- `Shape::Circle` defined here...8 | Shape::Circle => "circle", // ❌ `Circle` menyimpan sebuah nilai | ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Shape::Circle(_)`Ini program yang menghasilkan error tersebut:
enum Shape { Circle(f64), Square(f64),}
fn name(shape: &Shape) -> &'static str { match shape { Shape::Circle => "circle", // ❌ `Circle` menyimpan sebuah nilai Shape::Square(_) => "square", }}
fn main() { println!("{}", name(&Shape::Circle(1.0)));}Apa artinya
Section titled “Apa artinya”^^^ menunjuk ke Shape::Circle di baris 8, dan --- di baris 2 menunjukkan cara varian itu didefinisikan: Circle(f64), sebuah varian tuple yang membawa satu f64. Pattern yang hanya berupa nama, tanpa apa pun di belakangnya, harus salah satu dari tiga hal ini:
- unit struct, seperti
struct Empty; - varian unit, yaitu varian tanpa data, seperti
Shape::EmptyatauNone - konstanta, seperti
const LIMIT: u32 = 100;
Shape::Circle bukan salah satunya. Baris help langsung memberi perbaikannya: Shape::Circle(_), artinya “sebuah lingkaran, apa pun nilainya”.
Judul E0532 yang lain adalah kebalikannya: expected tuple struct or tuple variant, found unit variant `Status::Active` (atau found struct, atau found constant). Di situ, kamu yang menulis tanda kurung setelah sebuah nama, padahal hal yang kamu sebut tidak menerima nilai dalam tanda kurung.
Ini seperti formulir yang bertanya “Hewan peliharaan: anjing (nama: ____)”. Kalau kamu hanya menulis “anjing”, kotak namanya kosong. Kalau kamu menulis “ikan (nama: Bubbles)” padahal formulirnya hanya bilang “ikan” tanpa kotak, kamu menambah kotak yang memang tidak ada.
Kenapa Rust melakukan ini
Section titled “Kenapa Rust melakukan ini”Setiap struct dan varian enum punya salah satu dari tiga bentuk, dan kamu menulisnya dengan cara yang sama saat membuatnya maupun saat mencocokkannya (lihat Enum bisa menyimpan data):
| Jenis | Membuatnya | Mencocokkannya |
|---|---|---|
Unit: Empty |
Shape::Empty |
Shape::Empty |
Tuple: Circle(f64) |
Shape::Circle(1.0) |
Shape::Circle(r) atau Shape::Circle(..) |
Struct: Rect { w: f64, h: f64 } |
Shape::Rect { w: 2.0, h: 3.0 } |
Shape::Rect { w, h } atau Shape::Rect { .. } |
Karena bentuknya ketat, sebuah pattern selalu terlihat seperti nilai yang dicocokkannya, jadi kamu bisa membaca sebuah match dan langsung tahu data apa yang ada di setiap cabang. Ini juga membantu saat kamu mengubah sebuah tipe: kalau Empty nanti mendapat nilai dan menjadi Empty(u32), setiap cabang lama Shape::Empty ditandai, alih-alih diam-diam mencocokkan sesuatu yang baru.
Cara memperbaikinya
Section titled “Cara memperbaikinya”Perbaikan 1: Tambahkan (_), (..), atau nama untuk nilainya
Section titled “Perbaikan 1: Tambahkan (_), (..), atau nama untuk nilainya”Pilih ini kalau pesannya bilang found tuple variant atau found tuple struct, yaitu E0532 yang paling sering muncul. Pakai _ untuk setiap nilai yang tidak kamu butuhkan, .. untuk melewatkan semuanya sekaligus, atau sebuah nama kalau kamu ingin memakai nilainya:
enum Shape { Circle(f64), Rect(f64, f64), Empty,}
fn name(shape: &Shape) -> &'static str { match shape { Shape::Circle(_) => "lingkaran", // ✅ satu field, diabaikan Shape::Rect(..) => "persegi panjang", // ✅ berapa pun field-nya, semuanya diabaikan Shape::Empty => "kosong", // varian unit: tanpa tanda kurung }}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle(r) => 3.14 * r * r, // ✅ ikat field-nya karena kita membutuhkannya Shape::Rect(w, h) => w * h, Shape::Empty => 0.0, }}
fn main() { let shapes = [Shape::Circle(1.0), Shape::Rect(2.0, 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.14persegi panjang: 6.00kosong: 0.001 lingkaran(..) praktis untuk varian dengan beberapa nilai, dan tetap berfungsi kalau nanti kamu menambah satu nilai lagi. Lihat Mengabaikan bagian dengan _ dan ...
Perbaikan 2: Hapus () dari varian unit
Section titled “Perbaikan 2: Hapus () dari varian unit”Pilih ini kalau pesannya bilang found unit variant atau found unit struct. Variannya tidak menyimpan data, jadi tidak ada yang bisa dimasukkan ke dalam tanda kurung:
error[E0532]: expected tuple struct or tuple variant, found unit variant `Status::Active` --> src/main.rs:8:9 |2 | Active, | ------ `Status::Active` defined here...8 | Status::Active() => "active", // ❌ `Active` tidak menyimpan data | ^^^^^^^^^^^^^^^^ help: use this syntax instead: `Status::Active`Artinya: yang diharapkan struct tuple atau varian tuple, tapi yang ditemukan varian unit, dan help-nya menyarankan menulis Status::Active saja. Program di baliknya:
enum Status { Active, Banned(String),}
fn label(s: &Status) -> &'static str { match s { Status::Active() => "active", // ❌ `Active` tidak menyimpan data Status::Banned(_) => "banned", }}
fn main() { println!("{}", label(&Status::Active));}Tulis namanya saja, baik di pattern maupun saat kamu membuat nilainya:
#[derive(Debug)]enum Status { Active, Banned(String),}
fn label(s: &Status) -> String { match s { Status::Active => String::from("aktif"), // ✅ varian unit: tanpa () Status::Banned(reason) => format!("diblokir ({})", reason), }}
fn main() { println!("{}", label(&Status::Active)); println!("{}", label(&Status::Banned(String::from("spam")))); let s = Status::Active; // ✅ dan tanpa () juga saat membuatnya println!("{:?}", s);}Output:
aktifdiblokir (spam)ActiveKalau kamu memang ingin variannya membawa data, ubah definisinya saja, misalnya Active(u64) untuk timestamp “sejak kapan”, lalu Status::Active(_) menjadi pattern yang benar.
Perbaikan 3: Pakai kurung kurawal untuk struct dengan field bernama
Section titled “Perbaikan 3: Pakai kurung kurawal untuk struct dengan field bernama”Pilih ini kalau pesannya bilang found struct. Struct dengan field bernama, struct Point { x: i32, y: i32 }, di-destructure dengan kurung kurawal dan nama field-nya, bukan dengan tanda kurung:
error[E0532]: expected tuple struct or tuple variant, found struct `Point` --> src/main.rs:8:9 |1 | / struct Point {2 | | x: i32,3 | | y: i32,4 | | } | |_- `Point` defined here...8 | let Point(x, y) = p; // ❌ `Point` punya field bernama | ^^^^^^^^^^^ help: use struct pattern syntax instead: `Point { x, y }`Artinya: Point adalah struct dengan field bernama, jadi rustc menyarankan sintaks pattern struct, Point { x, y }. Program di baliknya:
struct Point { x: i32, y: i32,}
fn main() { let p = Point { x: 3, y: 4 }; let Point(x, y) = p; // ❌ `Point` punya field bernama println!("{} {}", x, y);}Saran rustc, Point { x, y }, sudah tepat. Pakai field: nama kalau kamu ingin nama variabel yang berbeda:
struct Point { x: i32, y: i32,}
struct Meters(f64); // struct tuple: di sini tanda kurung memang benar
fn main() { let p = Point { x: 3, y: 4 }; let Point { x, y } = p; // ✅ kurung kurawal dan nama field-nya println!("x = {}, y = {}", x, y);
let q = Point { x: -1, y: 7 }; let Point { x: left, y: up } = q; // ✅ ganti nama sambil men-destructure println!("left = {}, up = {}", left, up);
let Meters(m) = Meters(2.5); // ✅ struct tuple, pattern tuple println!("{} m", m);}Output:
x = 3, y = 4left = -1, up = 72.5 mUntuk varian enum dengan field bernama, Shape::Rect(w, h) untuk Rect { w: f64, h: f64 }, kesalahan yang sama memberi kode lain, E0164. Perbaikannya sama: kurung kurawal.
Perbaikan 4: Pakai konstanta atau match guard, bukan pemanggilan fungsi
Section titled “Perbaikan 4: Pakai konstanta atau match guard, bukan pemanggilan fungsi”Pilih ini kalau pesannya bilang expected a pattern, found a function call. Pattern harus sudah diketahui saat kompilasi, dan pemanggilan fungsi tidak memenuhi syarat itu:
error[E0532]: expected a pattern, found a function call --> src/main.rs:7:14 |7 | Some(limit()) => "full", // ❌ pemanggilan fungsi tidak bisa jadi pattern | ^^^^^ not a tuple struct or tuple variant | = note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>Artinya: yang diharapkan sebuah pattern, tapi yang ditemukan pemanggilan fungsi, dan note:-nya mengingatkan bahwa pemanggilan fungsi tidak boleh ada di dalam pattern. Program di baliknya:
fn limit() -> u32 { 100}
fn status(users: Option<u32>) -> &'static str { match users { Some(limit()) => "full", // ❌ pemanggilan fungsi tidak bisa jadi pattern Some(_) => "open", None => "closed", }}
fn main() { println!("{}", status(Some(100)));}Kalau nilainya tidak pernah berubah, jadikan const; konstanta boleh dipakai di dalam pattern. Kalau nilainya harus dihitung, ikat nilainya ke sebuah nama dan bandingkan di match guard:
const LIMIT: u32 = 100; // konstanta boleh dipakai di dalam pattern
fn limit_for(premium: bool) -> u32 { if premium { 500 } else { 100 }}
fn status(users: Option<u32>) -> &'static str { match users { Some(LIMIT) => "penuh", // ✅ sebuah konstanta Some(_) => "buka", None => "tutup", }}
fn status_for(users: Option<u32>, premium: bool) -> &'static str { match users { Some(n) if n >= limit_for(premium) => "penuh", // ✅ panggil fungsinya di guard Some(_) => "buka", None => "tutup", }}
fn main() { println!("{}", status(Some(100))); println!("{}", status(Some(42))); println!("{}", status(None)); println!("{}", status_for(Some(100), false)); println!("{}", status_for(Some(100), true));}Output:
penuhbukatutuppenuhbukaMatch guard dijelaskan di Match guard: menambahkan if.
Di mana biasanya kamu melihatnya
Section titled “Di mana biasanya kamu melihatnya”Setelah varian unit mendapat nilai. Event::Logout tadinya varian unit, lalu kamu mengubahnya menjadi Logout(u64). Sekarang setiap cabang Event::Logout => memberi E0532. Perbaikannya: Event::Logout(_) =>, atau Event::Logout(at) => kalau kamu butuh nilainya.
Hanya ingin mengecek jenis sebuah nilai. Kalau kamu datang dari Java atau TypeScript, kamu mungkin menulis if let Shape::Circle = shape untuk bertanya “apakah ini lingkaran?”. Tulis if let Shape::Circle(_) = shape, atau matches!(shape, Shape::Circle(_)) untuk mendapat bool dengan cepat.
Tanpa awalan Shape::, kodenya E0530. Kalau kamu menulis nama saja, seperti Ok => atau Circle => setelah use Shape::*;, rustc membacanya sebagai variabel baru. Ia melaporkan E0530, match bindings cannot shadow tuple variants (binding di match tidak boleh menutupi varian tuple), dengan help try specify the pattern arguments: `Ok(..)` . Perbaikannya sama: tambahkan tanda kurungnya.
Error terkait
Section titled “Error terkait”- E0533: expected unit struct, unit variant or constant, found struct variant: kesalahan yang sama untuk varian dengan field bernama; tambahkan
{ .. }. - E0164: expected tuple struct or tuple variant, found struct variant: tanda kurung pada varian dengan field bernama, atau pada konstanta atau fungsi asosiasi.
- E0023: wrong number of fields in a tuple pattern (bahasa Inggris): tanda kurungnya sudah benar, tapi jumlah nama yang kamu berikan terlalu banyak atau terlalu sedikit.
- E0026: struct or variant does not have a field named x: nama field yang salah di dalam kurung kurawal sebuah pattern.
- E0004: non-exhaustive patterns: setelah cabang-cabangnya diperbaiki,
match-nya tetap harus mencakup setiap varian. - Semua error compiler: daftar lengkap halaman error.
Kuis singkat
Section titled “Kuis singkat”Kuis singkat
1. Untuk enum Shape { Circle(f64), Empty }, cabang match mana yang bisa dikompilasi?
2. rustc bilang "expected tuple struct or tuple variant, found unit variant Status::Active". Apa perbaikannya?
3. struct Point { x: i32, y: i32 }: bagaimana cara men-destructure-nya dengan let?
Skor: 0 / 3
Bacaan lebih lanjut
Section titled “Bacaan lebih lanjut”- E0532 — Rust error codes index (bahasa Inggris): penjelasan resmi error ini.
- Pattern Syntax — The Rust Book (bahasa Inggris): men-destructure struct dan enum, mengabaikan nilai dengan
_dan.., dan match guard. - Destructuring enums — Rust by Example (bahasa Inggris): mencocokkan varian unit dan varian tuple berdampingan.
- Destructuring structs — Rust by Example (bahasa Inggris): kurung kurawal untuk field bernama, tanda kurung untuk struct tuple.
- Patterns — The Rust Reference (bahasa Inggris): aturan persis untuk pattern path, pattern struct tuple, dan pattern struct.