SkillByAIOpen interactive version →

Lesson 8 / 25

Borrowing With References

&T and &mut T.

Use without owning

A reference borrows a value without taking ownership: &T is a shared (read-only) borrow, &mut T is an exclusive mutable borrow. Functions taking references let callers keep their values. clone() makes an explicit deep copy when you really need a second owned value; types that implement Copy (integers, floats, bool, char, tuples of Copy types) are duplicated implicitly because copying them is cheap.

Shared and mutable borrows, clone and Copy, run

I ran this with Rust 1.99.0 (cargo run, edition 2024, standard library only). length borrows name immutably, shout borrows it mutably and appends "!", and name stays usable afterwards. clone makes a separate String; a and b are both usable because i32 is Copy.

fn length(s: &String) -> usize { // borrow: no ownership taken
    s.len()
}

fn shout(s: &mut String) {        // mutable borrow
    s.push('!');
}

fn main() {
    let mut name = String::from("Asha");
    let n = length(&name);
    shout(&mut name);
    println!("{name} has {n} letters before shouting");

    let copy = name.clone();      // explicit deep copy
    let a = 7;
    let b = a;                    // i32 is Copy: both remain usable
    println!("{copy} {a} {b}");
}

Output:

Asha! has 4 letters before shouting
Asha! 7 7

Clone deliberately

clone() is fine when needed, but frequent clones to satisfy the compiler often hint at a design that could borrow instead.

Quick check: What does &mut T allow?

  • Taking ownership
  • Sharing the value with any number of readers while mutating
  • Mutating the borrowed value through an exclusive borrow
  • Copying the value
Answer

Mutating the borrowed value through an exclusive borrow — Exclusive mutable access.