Closures
Closures
/// Finds all strings in a list that contain the '@' character. fn find_emails(list: Vec<String>) -> Vec<String> { list.into_iter() .filter(|s| s.contains('@')) // <-- Closure. .collect() } fn main() { for s in find_emails(vec![ String::from("example"), String::from("example@example.com"), ]) { println!("{}", s); } }
Closure with Type Annotations
use std::thread; use std::time::Duration; /// Demonstrates closures with type annotations. fn main() { // Closures can use type annotations, as shown below. // Multiple statements can be enclosed in a block. let _expensive_closure = |num: u32| -> u32 { println!("Calculating slowly..."); thread::sleep(Duration::from_secs(2)); num }; }
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.
To force a move:
use std::thread; /// Demonstrates the use of the `move` keyword with closures. fn main() { let list = vec![1, 2, 3]; println!("Before defining closure: {:?}", list); // `list` is still available here. // `move` forces the closure to take ownership of the values it uses. thread::spawn(move || println!("From thread: {:?}", list)) .join() .unwrap(); }
Closures as Input Parameters
// This function demonstrates how to accept a closure as an input parameter. // The `F` in `fn apply<F>(f: F)` is a generic type parameter, allowing // the function to accept any type that satisfies the specified trait bounds. fn apply<F>(f: F) where F: FnOnce(), // The closure `f` takes no input and returns nothing. { f(); } // This function demonstrates how to accept a closure that takes an input // and returns a value. 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() { apply(|| println!("Applied")); }
std::ops::Fn
⮳: the closure uses the captured value by reference (&T
).std::ops::FnMut
⮳: the closure uses the captured value by mutable reference (&mut T
).std::ops::FnOnce
⮳: the closure uses the captured value by value (T
).
Functions may also be used as arguments.
Related Topics
- Functions.
- Rust Patterns.
- Functional Programming.