From 5bd2852ee5e7a273dc4745be22d355c1cc1b709a Mon Sep 17 00:00:00 2001 From: denton Date: Sat, 18 Nov 2023 17:45:20 -0500 Subject: [PATCH] feat: add refcell1 exercise Signed-off-by: denton --- exercises/19_smart_pointers/refcell1.rs | 52 +++++++++++++++++++++++++ info.toml | 14 +++++++ 2 files changed, 66 insertions(+) create mode 100644 exercises/19_smart_pointers/refcell1.rs diff --git a/exercises/19_smart_pointers/refcell1.rs b/exercises/19_smart_pointers/refcell1.rs new file mode 100644 index 00000000..729877b4 --- /dev/null +++ b/exercises/19_smart_pointers/refcell1.rs @@ -0,0 +1,52 @@ +// refcell1.rs +// +// Interior mutability is a design pattern in Rust that allows you to mutate +// data even when there are immutable references to that data; +// normally, this action is disallowed by the borrowing rules. + +// The RefCell type represents single ownership over the data it holds. +// Recall the borrowing rules in Rust: +// 1. At any given time, you can have either (but not both) one mutable +// reference or any number of immutable references. +// 2. References must always be valid. + +// With references and Box, the borrowing rules’ invariants are enforced at +// compile time. With RefCell, these invariants are enforced at runtime. +// With references, if you break these rules, you’ll get a compiler error. +// With RefCell, if you break these rules, your program will panic and exit. +// The RefCell type is useful when you’re sure your code follows the +// borrowing rules but the compiler is unable to understand and guarantee that. + +// I AM NOT DONE + +use std::cell::RefCell; + +#[derive(Debug)] +#[allow(dead_code)] +struct User { + name: RefCell, +} + +#[allow(dead_code)] +impl User { + fn name(&self) -> String { + self.name.borrow().to_string() + } + + // Note: do not use &mut self! + fn set_name(&self, name: String) { + todo!() + } +} + +fn main() { + let u = User { + name: RefCell::new("Alice".to_string()), + }; + println!("My name is {}!", *u.name.borrow()); + + let new_name = "Bob".to_string(); + u.set_name(new_name.clone()); + + println!("My name is {}!", *u.name.borrow()); +} diff --git a/info.toml b/info.toml index 887662ab..e35b0a84 100644 --- a/info.toml +++ b/info.toml @@ -1106,6 +1106,20 @@ Check out https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation on the `Cow` type. """ +[[exercises]] +name = "refcell1" +path = "exercises/19_smart_pointers/refcell1.rs" +mode = "compile" +hint = """ +Remember that RefCell allows for an immutable object to be modified. + +Use the .borrow_mut() method on the RefCell to get a mutable reference to +the underlying data. + +See https://doc.rust-lang.org/book/ch15-05-interior-mutability.html for more +information on RefCell. +""" + # THREADS [[exercises]]