Eh. When I see stuff like this I can’t help but feel that people are misplacing their enjoyment of immutability in general. Here is how I honestly feel about it:
- Not being able to get a
&mut U
from a&T
is one of the core principles of Rust. - Not being able to get a
&mut U
from an immutableT
is an annoyance (when writing code) that, in my experience, is almost always correctly solved by adding amut
. But, it has two great payoffs:
First, it makes the unused_mut
lint one of the top most useful bug-catching lints, right up there with unused bindings. Oftentimes I might know for instance that I want to collect some data from an iterator into a vector, and then sort it. Thanks to mut
being required I now have it trained in me to write let mut vec: Vec<_> =
in anticipation of the sort:
let mut vec = {
things.iter()
.some_long_and(complicated)
.pipeline_of(iterator, adapters)
.collect::<Vec<_>>()
};
but then after all of that, I often forget to finish what I started and actually call sort
!
Second, reading the code after it is written, anybody who sees mut
can expect that something will happen to the value after its initial assignment. (this is, of course, also thanks to the unused_mut
lint)
I can contrive an example where adding mut
is not the solution:
fn ancient_function() {
let items = {
things.iter()
.some_long_and(complicated)
.pipeline_of(iterator, adapters)
.collect::<Vec<_>>()
};
+ items.sort(); // sort the output that gets printed
print_report(&items);
save_file(items); // (note: expects items to be in original order)
}
but to make a mistake like that seems… rather careless, enough so that I doubt that the author would notice it even after the minor speedbump presented by the "missing mut
" error.