Lending without transferring
The previous lesson left an ergonomic problem. If passing a value moves it, then every function that merely reads something must give it back, and code becomes a chain of returns.
The fix is a reference: a way to access a value without owning it. Writing &x creates one, and the value's owner is unchanged.
fn length(s: &String) -> usize { s.len() }
let s = String::from("hello");
let n = length(&s); // borrowed, not moved
println!("{s} has {n}"); // s is still usable
This is called borrowing, and the name is precise: the reference has temporary access and must return it before the owner is done with the value.
The hard part is guaranteeing exactly that. A reference outliving the value it points to is a dangling pointer, which is the defect ownership was introduced to eliminate. So the compiler needs a rule strong enough to make that impossible, and it turns out one rule handles both dangling references and data races at once.

