Fn, FnMut, FnOnce
Trait closure
Fn, FnMut, FnOnce adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Learn Rust Coding, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Learn Rust Coding mencakup 4 pelajaran total.
Trait Closure
Setiap closure secara otomatis mengimplementasikan satu atau beberapa dari tiga trait berdasarkan cara closure menggunakan nilai yang ditangkap:
Fn— meminjam secara tidak mutabel.FnMut— meminjam secara mutabel.FnOnce— mengambil kepemilikan dan hanya dapat dipanggil sekali.
fn main() {
let x = 5;
let show = || println!("x is {}", x); // implements Fn
show();
show();
}Fn: Peminjaman Tidak Mutabel
Closure yang hanya membaca nilai yang ditangkap mengimplementasikan Fn. Closure tersebut dapat dipanggil berkali-kali tanpa mengubah apa pun.
fn main() {
let greeting = String::from("Hi");
let say = || println!("{}", greeting);
say();
say();
}FnMut: Peminjaman Mutabel
Closure yang mengubah nilai yang ditangkap mengimplementasikan FnMut. Variabel closure itu sendiri harus berupa mut agar dapat dipanggil.
fn main() {
let mut count = 0;
let mut increment = || {
count += 1;
println!("count {}", count);
};
increment();
increment();
}FnOnce: Mengambil Kepemilikan
Closure yang memindahkan nilai yang ditangkap keluar dari lingkungan mengimplementasikan FnOnce. Closure tersebut hanya dapat dipanggil satu kali.
fn main() {
let name = String::from("Ada");
let consume = move || {
let owned = name;
println!("consumed {}", owned);
};
consume();
}Hierarki Trait
Trait membentuk hierarki:
- Setiap
Fnjuga merupakanFnMutdanFnOnce. - Setiap
FnMutjuga merupakanFnOnce.
Jadi, Fn adalah yang paling fleksibel, sedangkan FnOnce paling terbatas.
fn main() {
let value = 42;
let read = || value; // Fn, so also FnMut and FnOnce
println!("{}", read());
}Meneruskan Fn ke Fungsi
Fungsi dapat menerima closure dengan menentukan trait yang diperlukan. Gunakan generik dengan batasan trait.
fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
f(x)
}
fn main() {
let double = |n| n * 2;
println!("{}", apply(double, 9));
}Menerima FnMut
Jika fungsi Anda perlu mengubah state yang ditangkap, minta FnMut dan tandai parameternya sebagai mut.
fn call_twice<F: FnMut()>(mut f: F) {
f();
f();
}
fn main() {
let mut total = 0;
call_twice(|| total += 1);
// note: total is borrowed during the call
}Menerima FnOnce
Jika fungsi hanya memanggil closure sekali dan mungkin membiarkannya menggunakan nilai, minta FnOnce.
fn run_once<F: FnOnce() -> String>(f: F) {
let result = f();
println!("{}", result);
}
fn main() {
let s = String::from("done");
run_once(move || s);
}Kata Kunci move
Kata kunci move memaksa closure untuk mengambil kepemilikan variabel yang ditangkap, bukan meminjamnya.
Hal ini penting ketika closure harus tetap hidup lebih lama daripada scope tempat closure dibuat, misalnya dalam thread.
fn main() {
let data = vec![1, 2, 3];
let printer = move || println!("{:?}", data);
printer();
}Cara Rust Memilih Trait
Anda tidak memilih trait secara manual. Kompilator menentukannya berdasarkan isi closure:
- Hanya membaca →
Fn - Mengubah →
FnMut - Memindahkan nilai yang ditangkap keluar →
FnOnce
fn main() {
let mut log = Vec::new();
let mut record = |x: i32| log.push(x); // FnMut
record(1);
record(2);
println!("{:?}", log);
}Memilih Batasan yang Tepat
Sebagai aturan umum:
- Terima
Fnjika Anda hanya perlu memanggil dan membaca. - Terima
FnMutjika closure mengubah state. - Terima
FnOncejika pemanggilan satu kali sudah cukup.
Pilih batasan paling longgar yang sesuai.
fn each<F: Fn(i32)>(items: &[i32], f: F) {
for &i in items {
f(i);
}
}
fn main() {
each(&[1, 2, 3], |n| println!("got {}", n));
}Pemeriksaan Singkat
Pasangkan perilaku closure dengan trait-nya.
Ringkasan
Tiga trait closure:
Fn— meminjam secara tidak mutabel dan dapat dipanggil berulang kali.FnMut— meminjam secara mutabel dan dapat mengubah state.FnOnce— mengambil kepemilikan dan hanya dapat dipanggil sekali.
Kompilator menginferensikan trait tersebut; move memaksa penangkapan kepemilikan.
fn main() {
let base = 5;
let adder = move |x: i32| x + base; // Fn, captures base by move
println!("{}", adder(10));
}Pertanyaan yang Sering Diajukan
Apakah pelajaran “Fn, FnMut, FnOnce” gratis?
Ya — teks lengkap “Fn, FnMut, FnOnce” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Learn Rust Coding, upgrade ke CoddyKit PRO. Kursus Learn Rust Coding mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Fn, FnMut, FnOnce”?
Trait closure Kamu berlatih Learn Rust Coding dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Learn Rust Coding?
Tidak diperlukan pengalaman sebelumnya. Learn Rust Coding di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Fn, FnMut, FnOnce” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Learn Rust Coding ini?
Ya. Setiap pelajaran Learn Rust Coding menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Mendefinisikan Fungsi
- Expression dan Pernyataan
- Closure
- Fn, FnMut, FnOnce