Borrowing & References
&T and &mut T: using values without owning them, and the rule that prevents dangling pointers and data races.
Moving values into every function would be impractical. Instead, functions usually borrow: they receive a reference (&T for read access, &mut T for write access) and the owner keeps the value. One rule governs borrows: at any time you can have either any number of shared references or exactly one mutable reference — and a reference can never outlive the value it points to.
Shared and mutable borrows
average(&readings) lends the vector read-only; readings is still usable afterwards.
calibrate(&mut readings, ...) lends it exclusively for modification; *v += offset changes each element.
r1 and r2 are two shared borrows at the same time — allowed.
r1 and r2 are not used after their println!, so the mutable borrow r3 is allowed (the compiler tracks where each borrow is last used).
The bug the rule prevents
fn get_name() -> &String { let s = String::from("x"); &s } fn get_name() -> String { String::from("x") }
Returning a reference to a local value would create a dangling pointer, so it does not compile. Return the owned value instead.
State the borrowing rule.
At any given time you can have either one mutable reference or any number of immutable references to a value, and references must always be valid (never outlive the value).
Why does pushing to a Vec while holding a reference to one of its elements fail to compile?
push may reallocate the vector's buffer, which would leave the reference dangling. push needs &mut self while the element reference is a live shared borrow, which the rule forbids.