Closures can capture the enclosing evironments. For example we can capture the `x` variable :
```rust
fn main() {
let x = 1;
let closure = |val| val + x;
assert_eq!(closure(2), 3);
}
```
From the syntax, we can see that closures are very convenient for on the fly usage. Unlike functions, both the input and return types of a closure can be inferred by the compiler.
```rust
fn main() {
// Increment via closures and functions.
fn function(i: i32) -> i32 { i + 1 }
// Closures are anonymous, here we are binding them to references
//
// These nameless functions are assigned to appropriately named variables.
let closure_annotated = |i: i32| -> i32 { i + 1 };
- Fn: the closure uses the captured value by reference (&T)
- FnMut: the closure uses the captured value by mutable reference (&mut T)
- FnOnce: the closure uses the captured value by value (T)
On a variable-by-variable basis, the compiler will capture variables in the least restrictive manner possible.
For instance, consider a parameter annotated as FnOnce. This specifies that the closure may capture by `&T`, `&mut T`, or `T`, but the compiler will ultimately choose based on how the captured variables are used in the closure.
Which trait to use is determined by what the closure does with captured value.
This is because if a move is possible, then any type of borrow should also be possible. Note that the reverse is not true. If the parameter is annotated as `Fn`, then capturing variables by `&mut T` or `T` are not allowed.
// A function which takes a closure as an argument and calls it.
// <F> denotes that F is a "Generic type parameter"
fn apply<F>(f: F) where
// The closure takes no input and returns nothing.
F: __ {
f();
}
// A function which takes a closure and returns an `i32`.
fn apply_to_3<F>(f: F) -> i32 where
// The closure takes an `i32` and returns an `i32`.
F: Fn(i32) -> i32 {
f(3)
}
fn main() {
use std::mem;
let greeting = "hello";
// A non-copy type.
// `to_owned` creates owned data from borrowed one
let mut farewell = "goodbye".to_owned();
// Capture 2 variables: `greeting` by reference and
// `farewell` by value.
let diary = || {
// `greeting` is by reference: requires `Fn`.
println!("I said {}.", greeting);
// Mutation forces `farewell` to be captured by
// mutable reference. Now requires `FnMut`.
farewell.push_str("!!!");
println!("Then I screamed {}.", farewell);
println!("Now I can sleep. zzzzz");
// Manually calling drop forces `farewell` to
// be captured by value. Now requires `FnOnce`.
mem::drop(farewell);
};
// Call the function which applies the closure.
apply(diary);
// `double` satisfies `apply_to_3`'s trait bound
let double = |x| 2 * x;
println!("3 doubled: {}", apply_to_3(double));
}
```
move closures may still implement `Fn` or `FnMut`, even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them. The `move` keyword only specifies the latter.