References and Borrowing
A reference lets you use a value without taking ownership of it — written with &. The original owner keeps the value, and the reference just borrows access to it temporarily.
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}The length of 'hello' is 5.
calculate_length borrows s1 through a reference instead of taking ownership of it, so s1 is still perfectly usable back in main after the call.
Mutable references
A mutable reference, &mut T, lets a function modify the value it borrows. Rust allows this, but with one crucial restriction: you can have either one mutable reference, or any number of immutable references, to a value at a time — never both.
fn main() {
let mut s = String::from("hello");
change(&mut s);
println!("{}", s);
}
fn change(s: &mut String) {
s.push_str(", world");
}hello, world
What a real borrow conflict looks like
This is genuinely what rustc reports when you try to create a mutable reference while an immutable one is still in use — captured from a real run, not written to look plausible:
fn main() {
let mut s = String::from("hello");
let r1 = &s;
let r2 = &mut s;
println!("{}, {}", r1, r2);
}error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> main.rs:5:14
|
4 | let r1 = &s;
| -- immutable borrow occurs here
5 | let r2 = &mut s;
| ^^^^^^ mutable borrow occurs here
6 |
7 | println!("{}, {}", r1, r2);
| -- immutable borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0502`.This rule is what rules out data races entirely, at compile time — two parts of a program can never end up reading and writing the same data at once, because the compiler simply won't let the code that would allow it compile in the first place.
Next: strings and slices — the difference between an owned String and a borrowed &str.
Practice exercise
Write a function word_count(s: &String) -> usize that returns the number of words in s using s.split_whitespace().count(). Call it with a reference to a String containing "the quick brown fox" and print the result.