From 1eb1add888b1514fbe802ce2ab7edf720ab107af Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 5 Mar 2025 19:44:46 +0100 Subject: [PATCH] Why have I never comitted this? --- src/bin/interior_mutability.rs | 55 +++++++++++++++++++++++++++ src/bin/move.rs | 19 +++++++++ src/bin/thread_interior_mutability.rs | 50 ++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 src/bin/interior_mutability.rs create mode 100644 src/bin/move.rs create mode 100644 src/bin/thread_interior_mutability.rs diff --git a/src/bin/interior_mutability.rs b/src/bin/interior_mutability.rs new file mode 100644 index 0000000..e393534 --- /dev/null +++ b/src/bin/interior_mutability.rs @@ -0,0 +1,55 @@ +// https://www.youtube.com/watch?v=HwupNf9iCJk + +use std::cell::{Cell, RefCell}; + +#[derive(Debug)] +// Could simplify this with Rc (see thread safe example) +struct Node<'a> { + // Cell for copyable values + val: Cell, + // RefCell probably better as there is no copying but can panic + str_val: RefCell, + adjacent: Vec<&'a Node<'a>>, +} + +fn add_one(node: &Node) { + let curr_val = node.val.get(); + node.val.set(curr_val + 1); + for adj in node.adjacent.iter() { + add_one(adj); + } +} + +fn add_urgency(node: &Node) { + node.str_val.borrow_mut().push('!'); + for adj in node.adjacent.iter() { + add_urgency(adj); + } +} + +fn main() { + let a = Node { + val: Cell::new(1), + str_val: RefCell::new(String::from("aaa")), + adjacent: vec![], + }; + + let b = Node { + val: Cell::new(2), + str_val: RefCell::new(String::from("bbb")), + adjacent: vec![&a], + }; + + let c = Node { + val: Cell::new(4), + str_val: RefCell::new(String::from("ccc")), + adjacent: vec![&a], + }; + dbg!(&a); + dbg!(&b); + dbg!(&c); + add_one(&b); + dbg!(&b); + add_urgency(&c); + dbg!(&c); +} diff --git a/src/bin/move.rs b/src/bin/move.rs new file mode 100644 index 0000000..abbc838 --- /dev/null +++ b/src/bin/move.rs @@ -0,0 +1,19 @@ +// https://www.youtube.com/watch?v=MDvImhzrWr4 + +fn c(f: F) { + f(); +} + +fn main() { + let mut v = vec![1, 2, 3]; + + // use move keyword to get around 'static lifetime issue + c(move || { + v.push(4); + }); // without 'static closure lifetime ends here and we have no borrow issue + + // cannot use v after moving the value + // this is where rc and refcell come into play + //v.push(5); + //dbg!(v); +} diff --git a/src/bin/thread_interior_mutability.rs b/src/bin/thread_interior_mutability.rs new file mode 100644 index 0000000..e1af26e --- /dev/null +++ b/src/bin/thread_interior_mutability.rs @@ -0,0 +1,50 @@ +// https://www.youtube.com/watch?v=HwupNf9iCJk + +use std::{ + sync::{Arc, RwLock}, + thread, +}; + +#[derive(Debug)] +struct Node { + // RwLock similar to RefCell but thread safe, + // can also use Mutex and then .lock() it instead of calling .read() or .write() + str_val: RwLock, + adjacent: Vec>, +} + +fn add_urgency(node: Arc) { + { + node.str_val.write().unwrap().push('!'); + } + for adj in node.adjacent.iter() { + add_urgency(adj.clone()); + } +} + +fn main() { + let a = Arc::new(Node { + str_val: RwLock::new(String::from("aaa")), + adjacent: vec![], + }); + + let b = Arc::new(Node { + str_val: RwLock::new(String::from("bbb")), + adjacent: vec![a.clone()], + }); + + let c = Arc::new(Node { + str_val: RwLock::new(String::from("ccc")), + adjacent: vec![a.clone()], + }); + + dbg!(a.clone()); + dbg!(b.clone()); + dbg!(c.clone()); + let t1_b = b.clone(); + let _t1 = thread::spawn(move || add_urgency(t1_b)).join(); + dbg!(c.clone()); + let t2_c = c.clone(); + let _t2 = thread::spawn(move || add_urgency(t2_c)).join(); + dbg!(c.clone()); +}