liveBook · Manning

Mutable reference

As explained in Learn Rust in a Month of Lunches

A mutable reference is a Rust reference that permits modification of its referent and must be the sole active reference to that referent.

A mutable reference lets you change a value without taking ownership of it. Declare the value with `mut`, then borrow it with `&mut`. For example, `let mut number = 8; let number_ref = &mut number;` makes `number_ref` a mutable reference to `number`. Its type is written `&mut i32` when `number` is an `i32`. section 2.5

To change the number, write `*number_ref += 10`. The `*` follows the reference to the value behind it; this is called dereferencing. Adding to `number_ref` directly would try to add to the reference rather than the number. The linked example prints `18`. section 2.5

fn main() {
    let mut my_number = 8;
    let num_ref = &mut my_number;
    *num_ref += 10;                 #1
    println!("{}", my_number);
 
    let second_number = 800;
    let triple_reference = &&&second_number;
    println!("Are they equal? {}", second_number == ***triple_reference);
}

A runnable example changes a number through `&mut` and uses `*` to reach values behind references. section 2.5

Rust permits only one mutable reference to a value at a time, and a mutable reference cannot be used alongside an immutable reference to that value. Any number of immutable references are fine when nobody is changing the data. Picture someone editing a shared presentation: viewers should not have to watch unexpected changes while they read it. section 2.5.1 section 2.5.4

A borrow conflict—and a correction

If `number_ref = &number` will be used later, creating `number_change = &mut number` in between produces compiler error `E0502`: the immutable borrow is still in use. Change the number through `number_change` first, then create and use `number_ref`. This works because the mutable borrow is no longer used when the immutable one begins. section 2.5.4

fn main() {
    let mut number = 10;
    let number_change = &mut number;
    *number_change += 10;
    let number_ref = &number;
    println!("{}", number_ref);
}

The corrected code changes the number before creating an immutable reference to print it. section 2.5.4

Functions can borrow mutably too: a parameter of type `&mut String` can change a caller’s string without taking ownership. The caller passes `&mut country`; the function can then append `"-Hungary"`. That differs from a parameter declared `mut name: String`, which takes ownership rather than receiving a reference. section 2.7

fn add_hungary(country_name: &mut String) {    #1
    country_name.push_str("-Hungary");         #2
    println!("Now it says: {country_name}");
}
 
fn main() {
    let mut country = String::from("Austria");
    add_hungary(&mut country);                 #3
}

A function accepts `&mut String` and appends to the borrowed string. section 2.7

How Learn Rust in a Month of Lunches covers it

How deep it goes
Works through `&mut`, dereferencing, reference rules, and compiler feedback, including when a mutable borrow ends after its last use.
Examples
Shows numeric updates, a shared-presentation analogy, a compiler borrow error and correction, and a function that appends to a string.
What it assumes
Introduces `&mut` and dereferencing in plain terms while building on mutable variables, references, and ownership.
What you can do after
Build it from scratch with `&mut`, dereference it to update a value, and pass it to a function without moving ownership.
How it connects
Connects mutable references to immutable references, borrowing, dereferencing, function parameters, and ownership.

Also explained in

Compare how 3 books explain mutable reference →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.