capypad
0 Tage Serie
rust / intermediate
Snippet

Rust Closures verstehen: Fn, FnMut und FnOnce

Rust Closures sind anonyme Funktionen, die ihre Umgebung erfassen. Die drei Closure-Traits repräsentieren unterschiedliche Ownership-Verhalten: Fn leiht unveränderlich aus, FnMut leiht veränderlich aus, und FnOnce übernimmt den Besitz. Das Verständnis dieser Traits ist entscheidend für das Schreiben von Higher-Order-Funktionen und effizienten Callback-Mustern.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
fn main() {
let x = 10;
 
// Fn: borrows values immutably
let print_x = || println!("x = {}", x);
print_x();
 
// FnMut: mutably borrows values
let mut counter = 0;
let mut increment = || {
counter += 1;
println!("Counter: {}", counter);
};
increment();
 
// FnOnce: consumes values (takes ownership)
let data = vec![1, 2, 3];
let consume_data = || {
println!("Data: {:?}", data);
// data is moved here
};
consume_data();
 
// Higher-order function taking closures
let result = apply_twice(5, |n| n * n);
println!("Result: {}", result);
}
 
fn apply_twice<F>(value: i32, f: F) -> i32
where
F: Fn(i32) -> i32,
{
f(f(value))
}
Erklärung
1
let print_x = || println!("x = {}", x);
Eine Closure, die x unveränderlich ausleiht - implementiert Fn Trait
2
let mut increment = || { counter += 1; ...
Eine Closure, die counter veränderlich ausleiht - implementiert FnMut Trait
3
let consume_data = || { println!("{:?}", data);
Eine Closure, die data in sich selbst verschiebt - implementiert FnOnce Trait
4
where F: Fn(i32) -> i32
Generische Bound, die den Closure-Typ angibt, den apply_twice akzeptiert