Guys, what is the difference between those two?
fn fun(mut x: Vec<usize>)
fn fun(x: &mut Vec<usize>)
Thank you
Guys, what is the difference between those two?
fn fun(mut x: Vec<usize>)
fn fun(x: &mut Vec<usize>)
Thank you
The first function receives the argument by value, while the second one receives a mutable reference.
There's no difference in the signature between a function with a mut
and a non-mut
by-value argument. The mut is merely a convenience feature that makes the binding mutable in the body. It behaves identically to re-binding the same parameter to a mut
variable would be.
Hi and thank you for your answer.
It seems bit inconsistent though. Why am I not allowed to write:
fn fun(x: mut Vec<usize>)
to mean:
fn fun(mut x: Vec<usize>)
?
Because the mutability is a property of the binding, not of the type.
mut Vec<usize>
is never valid alone. It may seems that &mut Vec<usize>
is a reference (&
) to a mut Vec<usize>
, but actually it is a mutable/exclusive reference (&mut
) to a Vec<usize>
. The mut
here is parsed together with the &
and not with the following type.
Meanwhile, mut x
is a pattern, just like the ones you can use in match
. The only difference is that it must be irrefutable, that is it must match any value. Irrefutable patterns are also allowed in let
for example, which is the reason you can write let mut x = ...
. This means you can also write stuff like fn foo((a, b): (i32, u8)) { ... }
, because (a, b)
is a pattern that always matches values of type (i32, u8)
.
In general patterns are always allowed whenever you can introduce a new "name" for a variable. I suggest you to read the corresponding chapter in the Rust book.
Another thing to note is that patterns in functions arguments are never part of the signature of the function, only the types. This might be surprising because it may seem that mut x
is requiring the caller to pass a mutable value, but there's no such concept as a "mutable value", only binding or references are mutable. Whenever you own something you always have the permission to mutate it, and so if you take ownership of something you are free to mutate it. The only reason that non-mut
bindings exist (and are the default) is that they are a good practice: they make it easier to reason that something will not be locally mutated. But once you give up ownership of that something then it doesn't matter anymore because for you it's like it doesn't exist anymore.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.