Rust Closures and Move Semanticfleeting
- External reference: https://doc.rust-lang.org/rust-by-example/fn/closures/input_parameters.html
- External reference: https://doc.rust-lang.org/rust-by-example/fn/closures/capture.html
- External reference: https://doc.rust-lang.org/book/ch13-01-closures.html
When taking a closure as an input parameter, the closure’s complete type must be annotated using one of a few traits. In order of decreasing restriction, they are:
- Fn: the closure captures by reference (&T)
- FnMut: the closure captures by mutable reference (&mut T)
- FnOnce: the closure captures by value (T)
Closures can capture values from their environment in three ways, which directly map to the three ways a function can take a parameter: taking ownership, borrowing mutably, and borrowing immutably
- FnOnce consumes the variables it captures from its enclosing scope, known as the closure’s environment. To consume the captured variables, the closure must take ownership of these variables and move them into the closure when it is defined. The Once part of the name represents the fact that the closure can’t take ownership of the same variables more than once, so it can be called only once.
- FnMut can change the environment because it mutably borrows values.
- Fn borrows values from the environment immutably.
When you create a closure, Rust infers which trait to use based on how the closure uses the values from the environment.
capturing to flexibly adapt to the use case, sometimes moving and sometimes borrowing. Closures can capture variables:
- by reference: &T
- by mutable reference: &mut T
- by value: T
They preferentially capture variables by reference and only go lower when required