&self = immutable borrow (read-only, multiple allowed). &mut self = mutable borrow (read-write, exclusive). The borrow checker enforces these rules at compile time.
&self — shared read access:
1struct Rectangle {2 width: f64,3 height: f64,4}56impl Rectangle {7 fn area(&self) -> f64 {8 self.width * self.height9 }1011 fn perimeter(&self) -> f64 {12 2.0 * (self.width + self.height)13 }1415 fn fits(&self, other: &Rectangle) -> bool {16 self.width <= other.width && self.height <= other.height17 }18}1920let rect = Rectangle { width: 10.0, height: 5.0 };21println!("Area: {}", rect.area()); // &self22println!("Perimeter: {}", rect.perimeter()); // &self — coexists
&mut self — exclusive write access:
1impl Rectangle {2 fn scale(&mut self, factor: f64) {3 self.width *= factor;4 self.height *= factor;5 }67 fn rotate(&mut self) {8 std::mem::swap(&mut self.width, &mut self.height);9 }10}1112let mut rect = Rectangle { width: 10.0, height: 5.0 };13rect.scale(2.0); // (20, 10)14rect.rotate(); // (10, 20)
When to use &self:
When to use &mut self:
Common mistakes:
let mut for &mut self methods.