# Capturing the Environment with Closures

## Problem Statement

After reading somthing about closure in "the book" of rust, I tried to create a counter with closure, the code is here, and **the build of the following code will fail**:

```rust
fn main() {
    let mut x = 0;
    let counter = || {
        x += 1; // IDE: cannot borrow `counter` as mutable, as it is not declared as mutable
        x
    };
    println!("{}", counter()); // IDE: cannot borrow as mutable
}
```

with an error:

```shell-session
$ cargo run
   Compiling counter v0.1.0 (file:///projects/counter)
error[E0596]: cannot borrow `counter` as mutable, as it is not declared as mutable
 --> src/main.rs:7:20
  |
3 |     let counter = || {
  |         ------- help: consider changing this to be mutable: `mut counter`
4 |         x += 1;
  |         - calling `counter` requires mutable binding due to mutable borrow of `x`
...
7 |     println!("{}", counter());
  |                    ^^^^^^^ cannot borrow as mutable

For more information about this error, try `rustc --explain E0596`.
error: could not compile `counter` due to previous error
```

## Resolution

When a variable in Rust is immutable, once a value is bound to a name, you can’t change that value. Since Rust’s closures are anonymous functions you can save in a variable or pass as arguments to other functions, it is still a variable, so maybe it should follow the rules of mutability.

OK, let me find some references.

As "[the book](https://doc.rust-lang.org/book/ch13-01-closures.html#capturing-the-environment-with-closures)" says:

> 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. These are encoded in the three `Fn` traits as follows:
>
> * `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.

So... In my code, the value `x` is borrowed, but by default, the closure is immutable. I should make the closure `FnMut` to change the environment.

Now, let's solve the problem!

I simply add a mut to the defination of counter, besides, some more lines call of counter is added for test:

```rust
fn main() {
    let mut x = 0;
    let mut counter = || {
        x += 1;
        x
    };
    println!("{}", counter());
    println!("{}", counter());
    println!("{}", counter());
    println!("{}", counter());
    println!("{}", counter());
}
```

and run it:

```shell-session
$ cargo run
   Compiling counter v0.1.0 (file:///projects/counter)
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s
     Running `target/debug/counter`
1
2
3
4
5
```

Amazing! The program runs as wished, and the problem has been resolved.

## Conclusion

As a Rust newbie, the mutability may be confused for me.&#x20;

To take advantage of the safety and easy concurrency that Rust offers, maybe I should do more coding to be familiar with the feature provided by the Rust language.

## Reference

1. [Closures: Anonymous Functions that Can Capture Their environment](https://doc.rust-lang.org/book/ch13-01-closures.html#capturing-the-environment-with-closures)
2. [Variables and Mutability](https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html)
