# 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://a.b.cr/notebook/language/rust/reference/capturing-the-environment-with-closures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
