Capturing the Environment with Closures
Mutable? Immutable?
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:
with an 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" 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. TheOnce
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:
and run it:
Amazing! The program runs as wished, and the problem has been resolved.
Conclusion
As a Rust newbie, the mutability may be confused for me.
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
Last updated