C.W.K.
Stream
Lesson 02 of 05 · published

Mutable References

~12 min · borrowing, mutable, aliasing, E0502

Level 0Rust Curious
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

Reading through & is half the story. To change a borrowed value, you need a mutable reference: &mut.

&mut — borrow to modify

&mut s lends a reference that can change the value. The function modifies the caller's data in place — no ownership transfer, no return needed. The value itself must be declared mut for this to be allowed; you can't take a mutable reference to something immutable.

The one big restriction

At any given time you may have either any number of immutable references or exactly one mutable reference to a value — never both. While a &mut exists, no other reference (mutable or not) to that value can coexist. This feels strict at first, and it's the single most important rule in the language.

Aliasing XOR mutation. Either many readers or one writer, never both at once. This one rule eliminates data races at compile time — if only one reference can write, and no one else can even read while it does, two threads can't corrupt the same data.

Why this prevents real bugs

Consider iterating a list while something else modifies it — a classic crash (iterator invalidation) in many languages. In Rust the borrow checker refuses: the iteration holds a reference, so a concurrent &mut won't compile. The bug is impossible, not merely discouraged.

Code

&mut borrows to modify in place·rust
fn add_excitement(s: &mut String) {
    s.push_str("!!!"); // modify the caller's String directly
}

fn main() {
    let mut msg = String::from("hello");
    add_excitement(&mut msg); // lend a mutable reference
    println!("{msg}");        // hello!!! — changed in place

    // Aliasing XOR mutation in action:
    let r1 = &msg;
    let r2 = &msg;            // many immutable borrows: fine
    println!("{r1} {r2}");
    // let w = &mut msg;      // error[E0502]: cannot borrow as mutable
    //                        // while immutable borrows are still in use
}

External links

Exercise

Write a function that takes &mut Vec<i32> and pushes the number 99 onto it. Call it, then print the vector to confirm it changed in place. Now try creating an immutable reference to the vector and calling the function while that reference is still used afterward — read the E0502 error.
Hint
The mutable borrow inside the function can't coexist with an immutable borrow that's still alive in the caller. Drop the last use of the immutable reference before the mutation.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue
💛 by Ttoriwarm

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.