Start learning free

LESSON 51 OF 348 · FUNCTIONS I

Borrowing & References in Rust in Rust

Lesson

In the previous lesson we saw that assigning a String to another variable moves it: the old owner dies. But most of the time we don't want to give a value away — we just want to look at it, or briefly edit it, and let the owner keep it. That is what references are for.

Creating a reference is called borrowing, and there are exactly two kinds:

  • &value — a shared (immutable) reference: read-only access, no ownership taken
  • &mut value — a mutable reference: read and write access, no ownership taken

Reading through &:

let city = String::from("Oslo");
let peek = &city;              // borrow — city is still the owner
println!("{}", peek);          // prints: Oslo
println!("{}", city);          // still works! Nothing moved.

Modifying through &mut:

let mut city = String::from("Oslo");
let editor = &mut city;        // the binding must be `mut` to allow this
editor.push_str(", Norway");
println!("{}", city);          // prints: Oslo, Norway

The borrowing rules (the part everyone trips on):

At any moment a value may have either many shared & references or exactly one &mut reference — never both, and never two &mut. Break the rule and the compiler stops you:

error[E0499]: cannot borrow `greeting` as mutable more than once at a time
 --> main.rs:4:13
  |
3 |     let a = &mut greeting;
  |             ------------- first mutable borrow occurs here
4 |     let b = &mut greeting;
  |             ^^^^^^^^^^^^^ second mutable borrow occurs here
5 |     a.push_str("!");
  |     - first borrow later used here

Mixing the two kinds while both are still in use fails the same way:

error[E0502]: cannot borrow `greeting` as mutable because it is also borrowed as immutable
 --> main.rs:4:18
  |
3 |     let reader = &greeting;
  |                  --------- immutable borrow occurs here
4 |     let writer = &mut greeting;
  |                  ^^^^^^^^^^^^^ mutable borrow occurs here
5 |     println!("{}", reader);
  |                    ------ immutable borrow later used here

The escape hatch: a borrow ends at its last use, not at the end of the block. If you finish using reader before creating writer, both fit in the same function and everything compiles.


Assignment
Follow the Coding Tutorial: create a mutable String named greeting holding "Hello", read it through a shared reference reader, then — after reader's job is done — append ", Rust!" through a mutable reference writer and print the result. Expected output:

reader sees = Hello
greeting = Hello, Rust!

Hint
Order matters: finish all reads through reader before you create writer, and the borrow checker will be happy.


STEP 1 OF 6
    Ctrl + Enter to check

    Borrowing And References in Rust

    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free