&self = shared, immutable borrow (multiple allowed, read-only). &mut self = exclusive, mutable borrow (one at a time, read-write). The borrow checker enforces these rules.
&self — immutable access:
1struct Cache {2 entries: std::collections::HashMap<String, String>,3}45impl Cache {6 fn get(&self, key: &str) -> Option<&str> {7 self.entries.get(key).map(|s| s.as_str())8 }910 fn contains(&self, key: &str) -> bool {11 self.entries.contains_key(key)12 }1314 fn len(&self) -> usize {15 self.entries.len()16 }17}1819let cache = Cache { entries: vec![("a".into(), "1".into())].into_iter().collect() };20println!("a: {:?}", cache.get("a")); // Some("1")21println!("len: {}", cache.len()); // 1
&mut self — mutable access:
1impl Cache {2 fn insert(&mut self, key: String, value: String) {3 self.entries.insert(key, value);4 }56 fn remove(&mut self, key: &str) -> Option<String> {7 self.entries.remove(key)8 }910 fn clear(&mut self) {11 self.entries.clear();12 }13}1415let mut cache = Cache { entries: HashMap::new() };16cache.insert("x".into(), "10".into());17cache.remove("x");
When to use &self:
When to use &mut self:
Common mistakes:
let mut for &mut self methods.