|
| 1 | +// refcell1.rs |
| 2 | +// |
| 3 | +// Interior mutability is a design pattern in Rust that allows you to mutate |
| 4 | +// data even when there are immutable references to that data; |
| 5 | +// normally, this action is disallowed by the borrowing rules. |
| 6 | + |
| 7 | +// The RefCell<T> type represents single ownership over the data it holds. |
| 8 | +// Recall the borrowing rules in Rust: |
| 9 | +// 1. At any given time, you can have either (but not both) one mutable |
| 10 | +// reference or any number of immutable references. |
| 11 | +// 2. References must always be valid. |
| 12 | + |
| 13 | +// With references and Box<T>, the borrowing rules’ invariants are enforced at |
| 14 | +// compile time. With RefCell<T>, these invariants are enforced at runtime. |
| 15 | +// With references, if you break these rules, you’ll get a compiler error. |
| 16 | +// With RefCell<T>, if you break these rules, your program will panic and exit. |
| 17 | +// The RefCell<T> type is useful when you’re sure your code follows the |
| 18 | +// borrowing rules but the compiler is unable to understand and guarantee that. |
| 19 | + |
| 20 | +// I AM NOT DONE |
| 21 | + |
| 22 | +use std::cell::RefCell; |
| 23 | + |
| 24 | +#[derive(Debug)] |
| 25 | +#[allow(dead_code)] |
| 26 | +struct User { |
| 27 | + name: RefCell<String>, |
| 28 | +} |
| 29 | + |
| 30 | +#[allow(dead_code)] |
| 31 | +impl User { |
| 32 | + fn name(&self) -> String { |
| 33 | + self.name.borrow().to_string() |
| 34 | + } |
| 35 | + |
| 36 | + // Note: do not use &mut self! |
| 37 | + fn set_name(&self, name: String) { |
| 38 | + todo!() |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +fn main() { |
| 43 | + let u = User { |
| 44 | + name: RefCell::new("Alice".to_string()), |
| 45 | + }; |
| 46 | + println!("My name is {}!", *u.name.borrow()); |
| 47 | + |
| 48 | + let new_name = "Bob".to_string(); |
| 49 | + u.set_name(new_name.clone()); |
| 50 | + |
| 51 | + println!("My name is {}!", *u.name.borrow()); |
| 52 | +} |
0 commit comments