&self provides immutable access — read but not modify. &mut self provides mutable access — read and modify, but exclusively (no other references while active).
&self — shared, immutable borrow:
1struct Config {2 width: u32,3 height: u32,4 title: String,5}67impl Config {8 fn dimensions(&self) -> (u32, u32) {9 (self.width, self.height)10 }1112 fn area(&self) -> u32 {13 self.width * self.height14 }1516 fn summary(&self) -> String {17 format!("{}: {}x{}", self.title, self.width, self.height)18 }19}2021let config = Config { width: 800, height: 600, title: "MyApp".into() };22let (w, h) = config.dimensions(); // &self23println!("{}", config.summary()); // &self — can coexist
&mut self — exclusive, mutable borrow:
1impl Config {2 fn resize(&mut self, width: u32, height: u32) {3 self.width = width;4 self.height = height;5 }67 fn set_title(&mut self, title: String) {8 self.title = title;9 }1011 fn scale(&mut self, factor: f64) {12 self.width = (self.width as f64 * factor) as u32;13 self.height = (self.height as f64 * factor) as u32;14 }15}1617let mut config = Config { width: 800, height: 600, title: "MyApp".into() };18config.resize(1920, 1080);19config.set_title("FullScreen".into());
When to use &self:
When to use &mut self:
Common mistakes:
let mut when calling &mut self methods.