How can you define and use a closure in Rust?

In Rust, a closure is a function-like object that can capture variables from its surrounding scope and can be stored in a variable or passed as an argument to another function. Closures are created using the || syntax, which is called the "closure expression".

Here is an example of a closure that captures a variable from its surrounding scope:

let x = 10; let closure = |y| x + y;

This closure captures the variable x and takes an argument y, and when called it returns the sum of x and y.

Here is an example of how to use the closure:

let result = closure(5); println!("Result: {}", result); // prints 15

Closures also have a type that is inferred by the Rust compiler at the point of use, and the type is called Fn, FnMut or FnOnce depending on how the closure captures its environment.

  • Fn closures are the most restrictive, they only allow the captured variables to be borrowed immutably.
  • FnMut closures are a bit less restrictive, they allow the captured variables to be borrowed mutably.
  • FnOnce closures are the most flexible, they allow the captured variables to be moved.

Here is an example of how to use closures with the different types:

let x = 10; let mut y = 20; let closure_fn = || x; // closure with type `Fn` let closure_fn_mut = || { y += 1; y }; // closure with type `FnMut` let closure_fn_once = move || x + y; // closure with type `FnOnce`

In this example, the first closure is of type Fn and only borrows x immutably, the second closure is of type FnMut and borrows y mutably, the third closure is of type FnOnce and move x and y from their original scope.

Closures are often used in Rust to pass as arguments to higher-order functions such as map, filter, fold, etc. These functions take closures as arguments and use them to manipulate the elements of an iterable.