Beginner Fundamentals
Borrowing
Borrowing lets you access a value without taking ownership of it. You create a reference with &, which the function can read but does not own.
Immutable references
fn length(s: &String) -> usize {
s.len()
} // s is a reference, nothing is dropped here
fn main() {
let text = String::from("borrowing");
let len = length(&text); // lend a reference
println!("{} has {} chars", text, len); // text still usable
}
Mutable references
To modify borrowed data, use &mut. The original variable must be mutable too.
fn add_excitement(s: &mut String) {
s.push('!');
}
fn main() {
let mut text = String::from("hello");
add_excitement(&mut text);
println!("{}", text); // hello!
}
The borrowing rules
At any given time you may have either:
- Any number of immutable references (
&T), or - Exactly one mutable reference (
&mut T).
You cannot mix them at the same time.
fn main() {
let mut value = 10;
let r1 = &value;
let r2 = &value; // many immutable refs are fine
println!("{} {}", r1, r2);
let m = &mut value; // ok now that r1 and r2 are no longer used
*m += 1;
println!("{}", m);
}
These rules prevent data races at compile time.