Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add refcell1 exercise #1779

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 52 additions & 0 deletions exercises/19_smart_pointers/refcell1.rs
Original file line number Diff line number Diff line change
@@ -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<T> 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<T>, the borrowing rules’ invariants are enforced at
// compile time. With RefCell<T>, these invariants are enforced at runtime.
// With references, if you break these rules, you’ll get a compiler error.
// With RefCell<T>, if you break these rules, your program will panic and exit.
// The RefCell<T> 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<String>,
}

#[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());
}
14 changes: 14 additions & 0 deletions info.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> 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]]
Expand Down