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
&Tborrows or one&mut Tat a time - Borrows end after last use; structure code to shorten borrow scopes
- Slices reference ranges without copying; lifetimes explain validity