Error Rust E0599: no method named X found (method tidak ditemukan)
E0599 artinya kamu memanggil sebuah method yang tidak bisa ditemukan Rust di tipe tersebut. Error ini sangat umum, dan penyebabnya biasanya salah satu dari beberapa hal: trait yang belum kamu import, Option yang belum kamu buka, Vec yang kamu perlakukan seperti iterator, atau sekadar salah ketik. Kabar baiknya, baris help: dari rustc sering langsung memberi tahu perbaikan yang tepat. Halaman ini bagian dari Penjelasan error compiler Rust.
Pesan error-nya
Section titled “Pesan error-nya”error[E0599]: no method named `write_all` found for struct `Stdout` in the current scope --> src/main.rs:5:9 |5 | out.write_all(b"Server started\n").unwrap(); | ^^^^^^^^^ | = note: the method is available for `Stdout` here | = help: items from traits can only be used if the trait is in scopehelp: trait `Write` which provides `write_all` is implemented but not in scope; perhaps you want to import it |1 + use std::io::Write; |Compiler bilang Stdout sebenarnya punya write_all, tapi method itu berasal dari trait Write yang belum di-import, lalu menyarankan baris use std::io::Write;.
Ini program yang menghasilkan error tersebut:
use std::io;
fn main() { let mut out = io::stdout(); out.write_all(b"Server started\n").unwrap();}Apa artinya
Section titled “Apa artinya”Tanda ^^^^ menunjuk nama method-nya, write_all, dan baris pertama memberi tahu tipe yang diperiksa Rust: Stdout. Jadi pesannya kira-kira berbunyi: “Aku sudah melihat Stdout dan tidak menemukan method bernama write_all yang boleh kupakai di sini.”
Tipe di baris pertama itu adalah petunjuk paling berguna di seluruh pesan. Kalau di situ tertulis Option<T>, Result<T, E>, Vec<_>, atau parameter tipe T padahal kamu mengharapkan yang lain, kamu langsung tahu perbaikan mana di bawah yang kamu butuhkan.
Kenapa Rust melakukan ini
Section titled “Kenapa Rust melakukan ini”Di Rust, banyak method bukan milik tipenya sendiri. Method itu datang dari sebuah trait. write_all berasal dari trait Write, dan Stdout mengimplementasikannya. Tapi method dari sebuah trait hanya bisa dipakai di file yang membawa trait itu ke dalam scope (cakupan), biasanya dengan baris use. Itulah arti “items from traits can only be used if the trait is in scope” (item dari trait hanya bisa dipakai kalau trait-nya ada di scope).
Aturan ini membuat kode tetap bisa ditebak. Dua crate bisa sama-sama menambahkan method bernama write_all ke tipe yang sama lewat trait yang berbeda. Kalau semua trait selalu aktif, kamu tidak bisa tahu pemanggilan itu maksudnya yang mana. Dengan aturan ini, hanya trait yang kamu import yang dihitung.
Penyebab lainnya datang dari tipe Rust yang ketat. Option<&str> bukan &str, jadi ia tidak punya method milik &str. Tipe generik T bisa berupa tipe apa saja, jadi Rust hanya mengizinkanmu memanggil method yang dijanjikan oleh bound pada T.
Cara memperbaikinya
Section titled “Cara memperbaikinya”Perbaikan 1: Import trait-nya
Section titled “Perbaikan 1: Import trait-nya”Pilih ini kalau help-nya bilang “items from traits can only be used if the trait is in scope”. Tambahkan baris use yang disarankan rustc.
use std::io::{self, Write};
fn main() { let mut out = io::stdout(); out.write_all(b"Server berjalan\n").unwrap();}Output:
Server berjalanHal yang sama terjadi dengan crate rand. Tanpa import, rng.random_range(1..=6) gagal, dan rustc memberi tahu trait mana yang perlu dibawa masuk:
help: trait `RngExt` which provides `random_range` is implemented but not in scope; perhaps you want to import it |1 + use rand::RngExt;Artinya: trait RngExt yang menyediakan random_range sudah diimplementasikan, tapi belum ada di scope, jadi import dulu.
Perhatikan: di rand 0.10 trait-nya bernama RngExt. Tutorial lama menulis use rand::Rng, dan di rand 0.10 import itu menghasilkan error yang persis sama. Ikuti baris help:, bukan tutorialnya.
Perbaikan 2: Keluarkan dulu nilainya dari Option atau Result
Section titled “Perbaikan 2: Keluarkan dulu nilainya dari Option atau Result”Pilih ini kalau tipe di error-nya Option<T> atau Result<T, E>. Nilai yang kamu mau ada di dalamnya, dan kamu harus mengeluarkannya dulu sebelum memanggil method-nya.
error[E0599]: no method named `to_uppercase` found for enum `Option<T>` in the current scope --> src/main.rs:4:39 |4 | println!("First guest: {}", first.to_uppercase()); | ^^^^^^^^^^^^ method not found in `Option<&&str>`Compiler mencari to_uppercase di Option<&&str>, bukan di string di dalamnya, dan tidak menemukannya.
first() mengembalikan Option, karena daftarnya bisa saja kosong. rustc menyarankan .expect(...), yang memang jalan, tapi akan crash kalau nilainya None. Biasanya lebih baik menangani kedua kemungkinan:
fn main() { let guests = vec!["ana", "bo", "chen"];
match guests.first() { Some(name) => println!("Tamu pertama: {}", name.to_uppercase()), None => println!("Belum ada tamu"), }
let shout = guests.last().map(|name| name.to_uppercase()); println!("Tamu terakhir: {:?}", shout);}Output:
Tamu pertama: ANATamu terakhir: Some("CHEN").map() menjalankan kodemu pada nilai di dalamnya dan tetap mempertahankan bungkus Option-nya. Untuk Result (misalnya dari .parse()), pakai match, .unwrap_or(...), atau ? di dalam fungsi yang mengembalikan Result. Lihat Option dan Result.
Perbaikan 3: Panggil .iter() pada Vec
Section titled “Perbaikan 3: Panggil .iter() pada Vec”Pilih ini kalau kamu memanggil .map(), .filter(), atau method iterator lain langsung pada Vec. Error-nya terlihat berbeda di sini:
error[E0599]: the method `map` exists for struct `Vec<{integer}>`, but its trait bounds were not satisfied --> src/main.rs:3:35 |3 | let curved: Vec<i32> = scores.map(|s| s + 5).collect(); | ^^^ | = note: the following trait bounds were not satisfied: `Vec<{integer}>: Iterator`Compiler bilang method map sebenarnya ada, tapi syaratnya tidak terpenuhi: Vec bukan Iterator.
Untuk beberapa method, seperti filter, pesannya lebih ramah. rustc bilang Vec<i32> “is not an iterator” (bukan iterator) dan menambahkan help: call `.into_iter()` first. Penyebabnya sama, perbaikannya juga sama.
Vec<{integer}>: Iterator “not satisfied” karena Vec adalah koleksi, bukan iterator. Minta iterator darinya dengan .iter() (meminjam isinya) atau .into_iter() (mengambil isinya):
fn main() { let scores = vec![70, 85, 92]; let curved: Vec<i32> = scores.iter().map(|s| s + 5).collect(); println!("{:?}", curved);}Output:
[75, 90, 97]Perbaikan 4: Tambahkan trait bound pada T generik
Section titled “Perbaikan 4: Tambahkan trait bound pada T generik”Pilih ini kalau error-nya bilang method tidak ditemukan “for type parameter T”. Di dalam fungsi generik, Rust hanya tahu apa yang dijanjikan oleh bound pada T. T polos tidak menjanjikan apa-apa, jadi ia tidak punya method sama sekali.
error[E0599]: no method named `to_string` found for type parameter `T` in the current scope --> src/main.rs:2:26 |1 | fn describe<T>(item: T) -> String { | - method `to_string` not found for this type parameter2 | format!("[{}]", item.to_string()) | ^^^^^^^^^ method cannot be called on `T` due to unsatisfied trait bounds |help: the following trait defines an item `to_string`, perhaps you need to restrict type parameter `T` with it: |1 | fn describe<T: ToString>(item: T) -> String { | ++++++++++Compiler menyarankan untuk membatasi T dengan trait ToString, karena trait itulah yang mendefinisikan to_string.
Tambahkan bound yang disarankan rustc. Sekarang hanya tipe yang bisa diubah menjadi string yang diterima:
fn describe<T: ToString>(item: T) -> String { format!("[{}]", item.to_string())}
fn main() { println!("{}", describe(42)); println!("{}", describe("siap"));}Output:
[42][siap]Di mana biasanya kamu melihatnya
Section titled “Di mana biasanya kamu melihatnya”- Salah ketik, atau method dari bahasa lain.
tasks.push_back(...)padaVecmenghasilkanhelp: you might have meant to use `push`, dantasks.lenght()menghasilkanhelp: there is a method `len` with a similar name. Perbaikannya: pakai nama yang disarankan rustc. - Memanggil
Type::new()yang belum pernah kamu tulis. Rust tidak memberi constructor gratis:Account::new("Ana", 100)gagal denganno associated function or constant named `new` found for struct `Account`. Perbaikannya: tambahkanimpl Account { fn new(owner: &str, balance: i64) -> Self { ... } }, atau buat langsung denganAccount { owner: ..., balance: ... }. Lihat Struct. - Memanggil associated function dengan titik. Kalau
fn new() -> Selftidak punya parameterself,acc.new()gagal dengan “this is an associated function, not a method” (ini associated function, bukan method). Perbaikannya: panggil lewat tipenya,Account::new().
Error terkait
Section titled “Error terkait”- E0425: cannot find value in this scope: namanya sendiri tidak terlihat, bukan method pada sebuah tipe.
- E0277: trait bound not satisfied: sebuah tipe tidak punya trait yang dibutuhkan fungsi atau operator. Sering muncul bersama E0599 di kode generik.
- E0308: mismatched types: kamu punya
Option<T>padahal yang diharapkanT, atau sebaliknya. - E0382: use of moved value: sering muncul setelah kamu beralih dari
.iter()ke.into_iter(). - Semua error compiler: daftar lengkap, dengan ringkasan singkat masing-masing.
Kuis singkat
Section titled “Kuis singkat”Kuis singkat
1. rustc bilang "items from traits can only be used if the trait is in scope". Apa yang sebaiknya kamu lakukan?
2. names.first().to_uppercase() gagal dengan E0599 untuk Option<&&str>. Kenapa?
3. Kamu memanggil scores.filter(...) pada Vec<i32> dan rustc bilang "Vec<i32> is not an iterator". Apa perbaikannya?
Skor: 0 / 3
Bacaan lebih lanjut
Section titled “Bacaan lebih lanjut”- E0599 — Rust error codes index (bahasa Inggris): penjelasan resmi error ini.
- Traits: Defining Shared Behavior — The Rust Book (bahasa Inggris): bagaimana trait menambahkan method ke tipe, dan cara kerja trait bound.
- Processing a Series of Items with Iterators — The Rust Book (bahasa Inggris):
iter(),into_iter(), dan method iterator sepertimap. Option— dokumentasi standard library (bahasa Inggris): semua method untuk mengeluarkan nilai dariOption.- The Rust prelude — dokumentasi standard library (bahasa Inggris): trait yang selalu ada di scope, dan kenapa
Writetidak termasuk.