Here are two function signatures I saw in the Rust documentation:
fn modify_foo(mut foo: Box<i32>) { *foo += 1; *foo } fn modify_foo(foo: &mut i32) { *foo += 1; *foo }
Why the different placement of mut
?
It seems that the first function could also be declared as
fn modify_foo(foo: mut Box<i32>) { /* ... */ }
My current understanding is, that mut has two effects: It allows to assign another value to the variable later on. It allows to modify the object that the variable refers to later on.
A mutable reference is a borrow to any type mut T , allowing mutation of T through that reference. The below code illustrates the example of a mutable variable and then mutating its value through a mutable reference ref_i . fn main() {
Although variables are immutable by default, you can make them mutable by adding mut in front of the variable name as you did in Chapter 2. Adding mut also conveys intent to future readers of the code by indicating that other parts of the code will be changing this variable's value.
There is no single reason that bindings are immutable by default, but we can think about it through one of Rust's primary focuses: safety. If you forget to say mut , the compiler will catch it, and let you know that you have mutated something you may not have intended to mutate.
If you're coming from C/C++, it might also be helpful to think of it basically like this:
// Rust C/C++ a: &T == const T* const a; // can't mutate either mut a: &T == const T* a; // can't mutate what is pointed to a: &mut T == T* const a; // can't mutate pointer mut a: &mut T == T* a; // can mutate both
You'll notice that these are inverses of each other. C/C++ take a "blacklist" approach, where if you want something to be immutable you have to say so explicitly, while Rust takes a "whitelist" approach, where if you want something to be mutable you have to say so explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With