GGistDev

Borrowing in Rust

Borrowing lets you reference data without taking ownership. The borrow checker enforces aliasing and lifetime rules at compile time.

Immutable borrows (&T)

You can have many immutable borrows simultaneously.

let s = String::from("abc");
let a = &s; let b = &s;
println!("{} {}", a, b);

Mutable borrows (&mut T)

You can have only one active mutable borrow and no immutable borrows at the same time.

let mut s = String::from("abc");
{
    let m = &mut s;
    m.push('!');
}
println!("{}", s);

Borrow scopes

Borrows end where their last use occurs; shorten scopes to allow subsequent borrows.

let mut s = String::from("hi");
let r = &s;
println!("{}", r); // r last used here
let m = &mut s;     // ok: r no longer in use
m.push('!');

Slices and indexing

Slices borrow ranges without copying.

let arr = [1,2,3,4];
let sl: &[i32] = &arr[1..3];

Lifetimes (preview)

Lifetimes describe how long references are valid; elision rules infer most cases.

fn len(s: &str) -> usize { s.len() }          // elided lifetime

More complex signatures may require explicit lifetimes.

Summary

  • Many &T borrows or one &mut T at a time
  • Borrows end after last use; structure code to shorten borrow scopes
  • Slices reference ranges without copying; lifetimes explain validity