Closures - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# Closures

Closures are functions that can capture the enclosing environment. For example, a closure that captures the `x` variable:

    |val| val + x

The syntax and capabilities of closures make them very convenient for on the fly usage. Calling a closure is exactly like calling a function. However, both input and return types can be inferred and input variable names must be specified.

Other characteristics of closures include:

- using `||` instead of `()` around input variables.
- optional body delimitation (`{}`) for a single line expression (mandatory otherwise).
- the ability to capture the outer environment variables.

    fn main() {
        let outer_var = 42;

        // A regular function can't refer to variables in the enclosing environment
        //fn function(i: i32) -> i32 { i + outer_var }
        // TODO: uncomment the line above and see the compiler error. The compiler
        // suggests that we define a closure instead.

        // Closures are anonymous, here we are binding them to references.
        // Annotation is identical to function annotation but is optional
        // as are the `{}` wrapping the body. These nameless functions
        // are assigned to appropriately named variables.
        let closure_annotated = |i: i32| -> i32 { i + outer_var };
        let closure_inferred  = |i     |          i + outer_var  ;

        // Call the closures.
        println!("closure_annotated: {}", closure_annotated(1));
        println!("closure_inferred: {}", closure_inferred(1));
        // Once closure's type has been inferred, it cannot be inferred again with another type.
        //println!("cannot reuse closure_inferred with another type: {}", closure_inferred(42i64));
        // TODO: uncomment the line above and see the compiler error.

        // A closure taking no arguments which returns an `i32`.
        // The return type is inferred.
        let one = || 1;
        println!("closure returning one: {}", one());

    }