## Closures

Rust gives you the ability to define closures, which are similar to functions. Instead of starting with a technical definition, let's see what closures look like, syntactically, and then we'll return to defining what they are. Listing 13-1 shows a small closure whose definition is assigned to the variable `add_one`, which we can then use to call the closure:

Filename: src/main.rs

    fn main() {
        let add_one = |x| x + 1;

        let five = add_one(4);

        assert_eq!(5, five);
    }

Listing 13-1: A closure that takes one parameter and adds one to it, assigned to the variable `add_one`

The closure definition, on the first line, shows that the closure takes one parameter named `x`. Parameters to closures go in between vertical pipes (`|`).

This is a minimal closure with only one expression as its body. Listing 13-2 has a closure with a bit more complexity:

Filename: src/main.rs

    fn main() {
        let calculate = |a, b| {
            let mut result = a * 2;

            result += b;

            result
        };

        assert_eq!(7, calculate(2, 3)); // 2 * 2 + 3 == 7
        assert_eq!(13, calculate(4, 5)); // 4 * 2 + 5 == 13
    }

Listing 13-2: A closure with two parameters and multiple expressions in its body

We can use curly brackets to define a closure body with more than one expression.

You'll notice a few things about closures that are different from functions defined with the `fn` keyword. The first difference is that we did not need to annotate the types of the parameters the closure takes or the value it returns. We can choose to add type annotations if we want; Listing 13-3 shows the closure from Listing 13-1 with annotations for the parameter's and return value's types:

Filename: src/main.rs

    fn main() {
        let add_one = |x: i32| -> i32 { x + 1 };

        assert_eq!(2, add_one(1));
    }

Listing 13-3: A closure definition with optional parameter and return value type annotations

The syntax of closures and functions looks more similar with type annotations. Let's compare the different ways we can specify closures with the syntax for defining a function more directly. We've added some spaces here to line up the relevant parts:

    fn  add_one_v1   (x: i32) -> i32 { x + 1 }  // a function
    let add_one_v2 = |x: i32| -> i32 { x + 1 }; // the full syntax for a closure
    let add_one_v3 = |x|             { x + 1 }; // a closure eliding types
    let add_one_v4 = |x|               x + 1  ; // without braces

The reason type annotations are not required for defining a closure but are required for defining a function is that functions are part of an explicit interface exposed to your users, so defining this interface rigidly is important for ensuring that everyone agrees on what types of values a function uses and returns. Closures aren't used in an exposed interface like this, though: they're stored in bindings and called directly. Being forced to annotate the types would be a significant ergonomic loss for little advantage.

Closure definitions do have one type inferred for each of their parameters and for their return value. For instance, if we call the closure without type annotations from Listing 13-1 using an `i8`, we'll get an error if we then try to call the same closure with an `i32`:

Filename: src/main.rs

    let add_one = |x| x + 1;

    let five = add_one(4i8);
    assert_eq!(5i8, five);

    let three = add_one(2i32);

The compiler gives us this error:

    error[E0308]: mismatched types
     -->
      |
    7 | let three = add_one(2i32);
      |                     ^^^^ expected i8, found i32

Since closures' types can be inferred reliably since they're called directly, it would be tedious if we were required to annotate their types.

Another reason to have a different syntax from functions for closures is that they have different behavior than functions: closures possess an environment.

### Closures Can Reference Their Environment

We've learned that functions can only use variables that are in scope, either by being `const` or being declared as parameters. Closures can do more: they're allowed to access variables from their enclosing scope. Listing 13-4 has an example of a closure in the variable `equal_to_x` that uses the variable `x` from the closure's surrounding environment:

Filename: src/main.rs

    fn main() {
        let x = 4;

        let equal_to_x = |z| z == x;

        let y = 4;

        assert!(equal_to_x(y));
    }

Listing 13-4: Example of a closure that refers to a variable in its enclosing scope

Here, even though `x` is not one of the parameters of `equal_to_x`, the `equal_to_x` closure is allowed to use `x`, since `x` is a variable defined in the scope that `equal_to_x` is defined. We aren't allowed to do the same thing that Listing 13-4 does with functions; let's see what happens if we try:

Filename: src/main.rs

    fn main() {
        let x = 4;

        fn equal_to_x(z: i32) -> bool { z == x }

        let y = 4;

        assert!(equal_to_x(y));
    }

We get an error:

    error[E0434]: can't capture dynamic environment in a fn item; use the || { ... }
    closure form instead
     -->
      |
    4 |     fn equal_to_x(z: i32) -> bool { z == x }
      |                                          ^

The compiler even reminds us that this only works with closures!

Creating closures that capture values from their environment is mostly used in the context of starting new threads. We'll show some more examples and explain more detail about this feature of closures in Chapter 16 when we talk about concurrency.

### Closures as Function Parameters Using the `Fn` Traits

While we can bind closures to variables, that's not the most useful thing we can do with them. We can also define functions that have closures as parameters by using the `Fn` traits. Here's an example of a function named `call_with_one` whose signature has a closure as a parameter:

    # #![allow(unused_variables)]
    #fn main() {
    fn call_with_one<F>(some_closure: F) -> i32
        where F: Fn(i32) -> i32 {

        some_closure(1)
    }

    let answer = call_with_one(|x| x + 2);

    assert_eq!(3, answer);

    #}

We pass the closure `|x| x + 2`, to `call_with_one`, and `call_with_one` calls that closure with `1` as an argument. The return value of the call to `some_closure` is then returned from `call_with_one`.

The signature of `call_with_one` is using the `where` syntax discussed in the Traits section of Chapter 10. The `some_closure` parameter has the generic type `F`, which in the `where` clause is defined as having the trait bounds `Fn(i32) -> i32`. The `Fn` trait represents a closure, and we can add types to the `Fn` trait to represent a specific type of closure. In this case, our closure has a parameter of type `i32` and returns an `i32`, so the generic bound we specify is `Fn(i32) -> i32`.

Specifying a function signature that contains a closure requires the use of generics and trait bounds. Each closure has a unique type, so we can't write the type of a closure directly, we have to use generics.

`Fn` isn't the only trait bound available for specifying closures, however. There are three: `Fn`, `FnMut`, and `FnOnce`. This continues the patterns of threes we've seen elsewhere in Rust: borrowing, borrowing mutably, and ownership. Using `Fn` specifies that the closure used may only borrow values in its environment. To specify a closure that mutates the environment, use `FnMut`, and if the closure takes ownership of the environment, `FnOnce`. Most of the time, you can start with `Fn`, and the compiler will tell you if you need `FnMut` or `FnOnce` based on what happens when the function calls the closure.

To illustrate a situation where it's useful for a function to have a parameter that's a closure, let's move on to our next topic: iterators.