Skip to content
Select theme

What is the difference between & and &mut?

Short answer: & is an immutable reference — a shared borrow that reads, and any number of them can exist at once. &mut is a mutable reference — an exclusive borrow that writes, and only one can exist at a time: many readers, or one writer, never both.

Take a function that reads a string and one that changes it:

hello!
hello!!

&String reads; &mut String writes. The caller’s message keeps its name and its value across all three calls. Nothing moves, and the second shout sees what add_bang did. Writing through the reference is an ordinary method call on the borrowed value: text.push('!') changes the original String, not a copy of it.

The let mut on message is what makes &mut message legal at all. Without it the compiler refuses the borrow, and why the keyword is required has that error.

Shared borrows don’t conflict with each other, so there’s no limit on how many can be alive:

Ada and Ada

Two references to one value, both used on the last line. None of them can change anything: & hands out read access and nothing else, so one reader can never invalidate another.

The moment a &mut exists, every other borrow has to be over. A read that is still alive when the write starts is an error:

error[E0502]: cannot borrow `name` as mutable because it is also borrowed as immutable
--> src/main.rs:4:18
|
3 | let reader = &name;
| ----- immutable borrow occurs here
4 | let writer = &mut name;
| ^^^^^^^^^ mutable borrow occurs here
5 |
6 | println!("{reader} {writer}");
| ------ immutable borrow later used here
For more information about this error, try `rustc --explain E0502`.

reader is used on the last line, so it is still alive when writer is created, and the compiler refuses the mutable borrow. The fix is to end the read before the write starts: print first, or put the reader in its own scope. That gets its own page later in this chapter.

Two writers overlap the same way:

error[E0499]: cannot borrow `scores` as mutable more than once at a time
--> src/main.rs:4:18
|
3 | let first = &mut scores;
| ----------- first mutable borrow occurs here
4 | let second = &mut scores;
| ^^^^^^^^^^^ second mutable borrow occurs here
5 |
6 | first.push(4);
| ----- first borrow later used here
For more information about this error, try `rustc --explain E0499`.

first is used two lines after second is created, so the two exclusive borrows overlap. The rule isn’t one &mut per value ever. It’s one at a time: the first borrow ends when its last use does, and a second one can start after that.

A function holding &mut Vec<T> can resize the buffer or overwrite the elements, because it knows nothing else is looking at the value while it works. That’s the trade: & gives every reader the same value, &mut gives one writer the whole thing. A function that took the value and handed it back would also work, but it forces the caller to rebind; returning ownership from a function is that shape.