Ownership and borrowing

Each value has one owner; pass & to lend it, &mut to let a function change it, and .clone() to copy it.

Runs in Zerethon IDE · Rust 1.87 Official Rust documentation ↗

Ownership is how Rust frees memory without a garbage collector. Assigning a String or Vec to another variable, or passing it to a function, moves it: the old name can no longer be used. Borrowing with & lends it instead.

main.rs
fn length(text: &str) -> usize {
    text.len()
}

fn add_exclamation(text: &mut String) {
    text.push('!');
}

fn consume(text: String) -> String {
    text.to_uppercase()
}

fn main() {
    let mut greeting = String::from("hello");
    println!("{}", length(&greeting));
    add_exclamation(&mut greeting);
    println!("{greeting}");

    let copy = greeting.clone();
    let loud = consume(greeting);
    // println!("{greeting}"); // error[E0382]: borrow of moved value: 'greeting'
    println!("{copy} {loud}");

    let a = 5;
    let b = a; // numbers are Copy: `a` is still usable
    println!("{a} {b}");
}

Output

5
hello!
hello! HELLO!
5 5
  • At any time a value has either any number of & borrows or exactly one &mut borrow, never both.
  • Small types such as numbers, bool and char are Copy: assigning copies them, nothing moves.
  • Prefer &str and &[T] as parameter types: they accept a String / Vec (with &) as well as literals and slices.
  • .clone() makes an independent copy; it is the simple fix while learning, at the cost of copying.