Created
September 15, 2023 02:33
-
-
Save hucancode/882e6998950c9dac2461515612d32626 to your computer and use it in GitHub Desktop.
Learn RefCell with recursive struct
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
John: RefCell { value: Person { name: "John", partner: Some((Weak)) } } | |
John's partner: Some("Susan") | |
Susan: RefCell { value: Person { name: "Susan", partner: Some((Weak)) } } | |
Susan's partner: Some("John") | |
John's partner after dropping Susan: | |
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:16:51 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{ | |
cell::RefCell, | |
rc::{Rc, Weak}, | |
}; | |
#[derive(Debug)] | |
struct Person { | |
name: String, | |
partner: Option<Weak<RefCell<Person>>>, | |
} | |
impl Person { | |
fn partner_name(&self) -> Option<String> { | |
self.partner | |
.as_ref() | |
.map(|partner| Weak::upgrade(partner).unwrap()) | |
.map(|partner| RefCell::borrow(&partner).name.clone()) | |
} | |
} | |
pub fn main() { | |
let susan = Rc::new(RefCell::new(Person { | |
name: "Susan".to_string(), | |
partner: None, | |
})); | |
let john = Rc::new(RefCell::new(Person { | |
name: "John".to_string(), | |
partner: Some(Rc::downgrade(&susan)), | |
})); | |
// Now we can actually set them to be each other's partner: | |
RefCell::borrow_mut(&susan).partner = Some(Rc::downgrade(&john)); | |
// Both `susan` and `john` are still accessible | |
println!("John: {:?}", john); | |
println!( | |
"John's partner: {:?}\n", | |
RefCell::borrow(&john).partner_name() | |
); | |
println!("Susan: {:?}", susan); | |
println!( | |
"Susan's partner: {:?}\n", | |
RefCell::borrow(&susan).partner_name() | |
); | |
// Note that `susan` and `john` do not keep each other alive, as they | |
// are only `Weak` references. Therefore dropping the `Rc` handle | |
// Will cause the `Weak` handle to lose the connection. | |
drop(susan); | |
println!("John's partner after dropping Susan:"); | |
println!("{:?}", RefCell::borrow(&john).partner_name()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment