ProgramGuru

Mutable references and exclusive access

Mutable references and exclusive access

A correction operation should change the original student mark rather than return an unrelated copy. A mutable reference provides access to update a borrowed value. Rust checks that this access does not overlap with conflicting uses, so the caller can see exactly when mutation is allowed.

What you’ll learn

  • Update a caller’s mark through &mut.
  • Identify conflicting shared and mutable uses.

Mutable references and exclusive access in action

  1. Shared read: 72

    The shared borrow is last used in the first print.

    Shared read: 72
  2. Exclusive correction: +8

    The later correction can therefore borrow score mutably, change 72 to 80 and finish.

    Exclusive correction: +8
  3. New shared read: 80

    The final print observes the updated integer after that mutable borrow ends.

    New shared read: 80
The shared borrow is last used in the first print. The later correction can therefore borrow score mutably, change 72 to 80 and finish. The final print observes the updated integer after that mutable borrow ends.

Mutable references and exclusive access explained

&mut score borrows the value mutably. Inside the function, *score dereferences that reference to reach the integer. Ordinary references to the same value must not be used in conflict with a live mutable borrow. Borrow lifetimes are often shorter than the enclosing block and can end after their last use.

Connect this idea with slices and reference lifetimes and channels, arc and mutex.

Work through the Rust program

Save the complete source as main.rs in the Rust environment. No standard input is needed.

Rust 2024 · complete program

fn correct(score: &mut i32) { *score += 8; }
fn main() {
  let mut score = 72;
  let before = &score;
  println!("Before: {before}");
  correct(&mut score);
  println!("After: {score}");
}

Expected output

Before: 72
After: 80

Follow the execution

The shared borrow is last used in the first print. The later correction can therefore borrow score mutably, change 72 to 80 and finish. The final print observes the updated integer after that mutable borrow ends.

Try the complete program in the Rust compiler. For tests, Cargo commands and local files, use the specified local environment.

Try a small variation

Your task: Why would printing before again after correct create a borrowing conflict?

Rust 2024 · complete program

fn correct(score: &mut i32) { *score += 8; }
fn main() {
  let mut score = 72;
  let before = &score;
  println!("Before: {before}");
  correct(&mut score);
  println!("After: {score}");
}

Worked answer

It would require the earlier shared borrow to remain in use across the mutable correction. Move its last use before the correction or obtain a new shared reference afterward.

Mistakes and limits to recognize

The rule concerns overlapping access to the same data, not a blanket ban on all references in a program. Distinct fields can sometimes be borrowed separately. Exclusive borrowing alone does not implement a thread-safe shared counter; synchronization types have separate contracts.

Check your understanding

Why would printing before again after correct create a borrowing conflict?
Choose one answer. You can try again.

Answer and explanation

It would require the earlier shared borrow to remain in use across the mutable correction.

It would require the earlier shared borrow to remain in use across the mutable correction. Move its last use before the correction or obtain a new shared reference afterward.

Take the idea into your next program

It would require the earlier shared borrow to remain in use across the mutable correction. Move its last use before the correction or obtain a new shared reference afterward. The rule concerns overlapping access to the same data, not a blanket ban on all references in a program.

Further reading: the official Rust Book on mutable references and exclusive access.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Slices and reference lifetimes →