Error Rust E0624: method is private (method privat)
E0624 artinya: method yang kamu panggil memang ada, tapi ditulis tanpa pub, jadi hanya kode di dalam modulnya yang boleh memanggilnya. Struct-nya boleh publik, modulnya juga. Method tetap mulai sebagai privat, satu per satu. Error ini sangat sering muncul tepat setelah kamu memindahkan sebuah tipe ke modulnya sendiri, dan perbaikannya biasanya menambahkan pub di depan fn. Halaman ini bagian dari Penjelasan error compiler Rust.
Pesan error-nya
Section titled “Pesan error-nya”error[E0624]: associated function `new` is private --> src/main.rs:18:38 | 7 | fn new() -> Account { // no `pub` | ------------------- private associated function defined here...18 | let mut account = bank::Account::new(); // ❌ private associated function | ^^^ private associated function
error[E0624]: method `add_interest` is private --> src/main.rs:19:13 |11 | fn add_interest(&mut self) { // no `pub` | -------------------------- private method defined here...19 | account.add_interest(); // ❌ private method | ^^^^^^^^^^^^ private methodCompiler melaporkan dua error: associated function new privat, dan method add_interest juga privat. Masing-masing menunjukkan tempat fungsi itu didefinisikan (defined here).
Ini program yang menghasilkan error tersebut:
mod bank { pub struct Account { balance: u64, }
impl Account { fn new() -> Account { // no `pub` Account { balance: 0 } }
fn add_interest(&mut self) { // no `pub` self.balance += self.balance / 100; } }}
fn main() { let mut account = bank::Account::new(); // ❌ private associated function account.add_interest(); // ❌ private method}rustc memakai dua nama di sini. Method menerima self (account.add_interest()). Associated function tidak punya self dan dipanggil dengan :: (Account::new()). Aturan dan perbaikannya sama untuk keduanya.
Apa artinya
Section titled “Apa artinya”Setiap error punya dua panah. Panah ^^^ adalah pemanggilanmu. Panah --- menunjukkan baris fn yang tidak punya pub. Jadi pesannya memberi tahu persis di mana kamu harus menambahkannya.
Berada di dalam impl Account tidak membuat sebuah method menjadi publik, bahkan kalau Account sudah pub. Bayangkan sebuah restoran: menunya publik, jadi kamu bisa memesan hidangan (method pub). Dapur punya langkah-langkahnya sendiri, seperti “iris bawang”, yang tidak bisa kamu minta secara langsung. Itulah method privat.
Kenapa Rust melakukan ini
Section titled “Kenapa Rust melakukan ini”Semua yang ada di Rust privat secara default, dan method tidak terkecuali (lihat Modul). Privasi dimiliki oleh modul tempat blok impl ditulis: kode apa pun di mod bank boleh memanggil add_interest, dan kode di luarnya tidak.
Ini membuat sebuah tipe bisa menyimpan method pembantu kecil yang hanya masuk akal kalau dijalankan dengan urutan yang benar. Misalnya add_interest hanya boleh berjalan sebulan sekali, setelah biaya administrasi dipotong. Kalau siapa saja bisa memanggilnya, suatu saat seseorang akan memanggilnya dua kali tanpa sengaja. Method pembantu yang privat ditambah satu method publik yang menjalankannya dengan benar membuat kesalahan itu mustahil terjadi.
Ini juga membuat pilihanmu tetap terbuka. Method privat bisa diganti namanya, digabung, atau dihapus kapan saja, karena compiler menjamin tidak ada kode di luar yang memakainya.
Cara memperbaikinya
Section titled “Cara memperbaikinya”Perbaikan 1: Tambahkan pub pada method-nya
Section titled “Perbaikan 1: Tambahkan pub pada method-nya”Pilih ini kalau method-nya memang dimaksudkan untuk dipanggil dari luar. Untuk new, hampir selalu begitu: constructor yang tidak bisa dipanggil siapa pun tidak banyak gunanya.
mod bank { pub struct Account { balance: u64, }
impl Account { pub fn new(opening: u64) -> Account { Account { balance: opening } }
pub fn add_interest(&mut self) { self.balance += self.balance / 100; // 1% }
pub fn balance(&self) -> u64 { self.balance } }}
fn main() { let mut account = bank::Account::new(1000); account.add_interest(); println!("Saldo: {}", account.balance());}Output:
Saldo: 1010Perbaikan 2: Panggil method publik yang memang disediakan untukmu
Section titled “Perbaikan 2: Panggil method publik yang memang disediakan untukmu”Pilih ini kalau method privatnya adalah pembantu, terutama di kode yang bukan kamu tulis. Sering ada method publik yang memanggilnya untukmu, dengan urutan yang benar dan pemeriksaan yang tepat. Di sini, membiarkan add_interest tetap privat adalah desain yang benar:
mod bank { pub struct Account { balance: u64, }
impl Account { pub fn new(opening: u64) -> Account { Account { balance: opening } }
// Pintu masuk publik: satu panggilan mengerjakan seluruh bulan, dengan urutan yang benar. pub fn close_month(&mut self) { self.charge_fee(); self.add_interest(); }
pub fn balance(&self) -> u64 { self.balance }
// Pembantu privat: memanggilnya sendirian, atau dua kali, memberi hasil yang salah. fn charge_fee(&mut self) { self.balance = self.balance.saturating_sub(5); }
fn add_interest(&mut self) { self.balance += self.balance / 100; } }}
fn main() { let mut account = bank::Account::new(1000); account.close_month(); println!("Setelah satu bulan: {}", account.balance()); // account.add_interest(); // ❌ E0624: method `add_interest` is private}Output:
Setelah satu bulan: 1004Aturan yang bagus: jadikan sebuah method pub hanya kalau memanggilnya sendirian, kapan saja tidak bisa merusak struct-nya. Kalau method itu hanya masuk akal sebagai satu langkah dari sesuatu yang lebih besar, biarkan privat dan sediakan yang lebih besar itu.
Perbaikan 3: Pakai pub(crate) untuk “hanya kodeku”
Section titled “Perbaikan 3: Pakai pub(crate) untuk “hanya kodeku””Pilih ini kalau modul lain di crate-mu butuh method itu, tapi orang yang memakai library-mu tidak boleh. pub(super) (hanya modul induknya) bekerja dengan cara yang sama; halaman E0603 punya tabel semua tingkatannya.
mod shop { pub struct Cart { prices: Vec<u32>, }
impl Cart { pub fn new() -> Cart { Cart { prices: Vec::new() } }
pub fn add(&mut self, price: u32) { self.prices.push(price); }
// Hanya untuk kode kita sendiri (seperti struk), bukan untuk pengguna library. pub(crate) fn total(&self) -> u32 { self.prices.iter().sum() } }}
mod receipt { pub fn print(cart: &crate::shop::Cart) { println!("Total: {}", cart.total()); }}
fn main() { let mut cart = shop::Cart::new(); cart.add(3); cart.add(5); receipt::print(&cart);}Output:
Total: 8Satu hal yang perlu diwaspadai: di package yang punya src/lib.rs sekaligus src/main.rs, keduanya adalah dua crate. pub(crate) fn total di lib.rs itu privat bagi main.rs:
error[E0624]: method `total` is private --> src/main.rs:3:25 | 3 | println!("{}", cart.total()); | ^^^^^ private method | ::: src/lib.rs:10:5 |10 | pub(crate) fn total(&self) -> u32 { | --------------------------------- private method defined hereCompiler bilang method total privat. Baris ::: src/lib.rs menunjukkan bahwa method itu didefinisikan di crate lain, yaitu library-nya.
Di situ, pakai pub biasa. Lihat Cargo dan crate.
Perbaikan 4: Pindahkan kode yang membutuhkannya ke dalam modul
Section titled “Perbaikan 4: Pindahkan kode yang membutuhkannya ke dalam modul”Pilih ini kalau method-nya memang harus tetap privat, tapi ada kode yang tetap membutuhkannya, seperti pemeriksaan audit atau test. Kode di modul yang sama boleh memanggilnya, begitu juga modul anak: modul di dalam bank bisa melihat semua yang privat di bank.
mod bank { pub struct Account { balance: u64, }
impl Account { pub fn new(opening: u64) -> Account { Account { balance: opening } }
fn is_suspicious(&self) -> bool { self.balance > 10_000 } }
// Modul anak boleh memakai semua yang privat di modul induknya. pub mod audit { pub fn check(account: &super::Account) -> &'static str { if account.is_suspicious() { "perlu diperiksa" } else { "aman" } } }}
fn main() { let small = bank::Account::new(500); let big = bank::Account::new(50_000); println!("kecil: {}", bank::audit::check(&small)); println!("besar: {}", bank::audit::check(&big));}Output:
kecil: amanbesar: perlu diperiksaUnit test bekerja dengan cara yang sama. mod tests yang ditulis di dalam bank (atau di bagian bawah src/bank.rs) adalah modul anak, jadi ia boleh memanggil method privat. Lihat Testing:
#[cfg(test)]mod tests { use super::*;
#[test] fn not_suspicious_when_small() { let account = Account::new(500); assert!(!account.is_suspicious()); // privat, tapi boleh di sini }}Di mana biasanya kamu melihatnya
Section titled “Di mana biasanya kamu melihatnya”Blok impl di modul yang berbeda. Privasi dimiliki oleh modul tempat impl ditulis, bukan oleh struct-nya. Kalau Order tinggal di mod model tapi kamu menulis impl Order { fn with_tax(&self) ... } di dalam mod pricing, maka main mendapat method `with_tax` is private, yang menunjuk ke mod pricing. Perbaikannya: pub fn with_tax, atau pub(crate).
Memakai method sebagai nilai fungsi. accounts.iter().map(bank::Account::audit) adalah pemanggilan yang sama dengan penulisan berbeda, jadi memberi E0624 yang sama. Perbaikannya pun sama.
Method trait. Kamu tidak pernah menulis pub pada method di dalam impl SomeTrait for Type. Method itu sepublik trait-nya, dan menambahkan pub justru error: error[E0449]: visibility qualifiers are not permitted here (penanda visibilitas tidak diizinkan di sini). Kalau sebuah method trait seolah hilang, kamu akan mendapat E0599, dan perbaikannya adalah use trait-nya.
Method privat milik sebuah crate. Kamu menemukan method yang pas di source code sebuah crate di GitHub, tapi method itu tidak pub. Kamu tidak bisa memanggilnya, dan pembuatnya bisa mengubahnya di rilis mana pun. Cari method publik yang melakukan hal yang sama di halaman crate itu di docs.rs; hanya item pub yang tampil di sana.
Error terkait
Section titled “Error terkait”- E0603:
function `x` is private. Ide yang sama untuk fungsi biasa, struct, dan modul. - E0616:
field `x` of struct `Y` is private, saat membaca atau mengubah sebuah field. - E0451: field privat saat membuat struct dengan
Y { ... }. Biasanya diperbaiki denganpub fn new. - E0599:
no method named `x` found. Method itu tidak ada untuk tipe tersebut, atau trait-nya belum masuk scope. - Semua error compiler: daftar lengkap halaman error.
Kuis singkat
Section titled “Kuis singkat”Kuis singkat
1. pub struct Timer punya impl Timer { fn start() -> Timer { ... } } di dalam mod clock. Apa yang terjadi saat main memanggil clock::Timer::start()?
2. Kode mana yang boleh memanggil method privat yang didefinisikan di mod bank?
3. add_interest yang privat hanya boleh berjalan sebulan sekali, setelah biaya dipotong. Apa perbaikan terbaik untuk E0624?
Skor: 0 / 3
Bacaan lebih lanjut
Section titled “Bacaan lebih lanjut”- E0624 — Rust error codes index (bahasa Inggris): penjelasan resmi dengan contoh minimal.
- Method Syntax — The Rust Book (bahasa Inggris): method, associated function, dan blok
impl. - Paths for Referring to an Item in the Module Tree — The Rust Book (bahasa Inggris): membuka item dengan
pub, langkah demi langkah. - Testing Private Functions — The Rust Book (bahasa Inggris): kenapa unit test boleh memanggil kode privat.
- Visibility and privacy — The Rust Reference (bahasa Inggris): aturan persisnya, termasuk
pub(crate),pub(super), danpub(in path).