Closure Traits: Fn, FnMut, FnOnce
In this page:
Fn: Read-Only Captures
A closure that only reads captured variables implements Fn, and can be called multiple times without any restriction.
Example: Fn: Read-Only Captures
fn main() {
let greeting = String::from("Hello");
let greet = || println!("{}, world!", greeting);
greet();
greet();
}
Login to try C/C++/Java/PHP code in the editor
FnMut: Mutating Captures
A closure that mutates a captured variable implements FnMut; the variable holding the closure must itself be mut to call it.
Example: FnMut: Mutating Captures
fn main() {
let mut count = 0;
let mut increment = || {
count += 1;
println!("count is now {}", count);
};
increment();
increment();
}
Login to try C/C++/Java/PHP code in the editor
FnOnce: Consuming Captures
A closure that moves a captured variable out of itself (for example, returning owned data) implements only FnOnce, meaning it can be called at most one time.
Example: FnOnce: Consuming Captures
fn main() {
let text = String::from("consumed");
let consume = move || {
let owned = text;
println!("Consumed inside closure: {}", owned);
};
consume();
}
Login to try C/C++/Java/PHP code in the editor
Forcing Ownership with move
The move keyword forces a closure to take ownership of every variable it captures, rather than borrowing them, which is required when the closure needs to outlive its original scope.
Example: Forcing Ownership with move
fn main() {
let data = vec![1, 2, 3];
let owns_data = move || println!("Owned inside closure: {:?}", data);
owns_data();
}
Login to try C/C++/Java/PHP code in the editor
- Trying to call an
FnOnceclosure more than once -- by definition it can only be called a single time. - Requiring
Fnin a function signature when the closure passed actually needs to mutate captured state, requiringFnMutinstead. - Forgetting the
movekeyword forces a closure to take ownership of captured variables instead of borrowing them.
Fnclosures can be called repeatedly and only borrow captured variables immutably.FnMutclosures can be called repeatedly and may mutate captured variables.FnOnceclosures can only be called once, since they consume (move) captured variables.- The
movekeyword forces a closure to take ownership of the variables it captures rather than borrowing them.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: