use std::cell::RefCell; use std::rc::Rc; // A MessageLogger struct that can hold a mutable list of messages // even if the logger itself is immutably referenced. struct MessageLogger { messages: RefCell>, } impl MessageLogger { fn new() -> MessageLogger { MessageLogger { messages: RefCell::new(Vec::new()), } } // This method takes an immutable reference to self (&self) // but can still mutate the internal Vec using RefCell. fn log_message(&self, message: &str) { // RefCell::borrow_mut() provides a runtime-checked mutable borrow. // If another mutable borrow exists, this will panic at runtime. self.messages.borrow_mut().push(String::from(message)); } fn print_messages(&self) { // RefCell::borrow() provides a runtime-checked immutable borrow. for msg in self.messages.borrow().iter() { println!("LOG: {}", msg); } } } fn main() { let logger = Rc::new(MessageLogger::new()); // Even though 'logger' is immutably bound (via Rc), // we can still call 'log_message' which mutates its internal state. logger.log_message("Application started."); logger.log_message("Performing task A."); let logger_clone = Rc::clone(&logger); logger_clone.log_message("Performing task B."); logger.print_messages(); // This would panic at runtime if another mutable borrow was active: // let mut_borrow1 = logger.messages.borrow_mut(); // let mut_borrow2 = logger.messages.borrow_mut(); // Panic! }