Skip to content

Instantly share code, notes, and snippets.

@davidlopezre
Last active February 9, 2022 10:20
Show Gist options
  • Save davidlopezre/99cca2e2a267a691f691ed07359cfde2 to your computer and use it in GitHub Desktop.
Save davidlopezre/99cca2e2a267a691f691ed07359cfde2 to your computer and use it in GitHub Desktop.
Demonstration of Rc and Weak references
use std::cell::RefCell;
use std::rc::Weak;
#[derive(Debug)]
pub struct Node<T> {
data: T,
// must be a RefCell because we want to store non Copy type `Vec`
// while allowing interior mutability (necessary for this cyclic type)
// this doesn't necessarily need to be weak, it is just for learning
// purposes
edges: RefCell<Vec<Weak<Node<T>>>>,
}
impl<T> Node<T> {
pub fn new(new_data: T) -> Node<T> {
Node {
data: new_data,
edges: RefCell::new(vec![]),
}
}
pub fn new_with_children(new_data: T, children: Vec<Weak<Node<T>>>) -> Node<T> {
Node {
data: new_data,
edges: RefCell::new(children),
}
}
pub fn add_child(&self, node: Weak<Node<T>>) {
self.edges.borrow_mut().push(node);
}
pub fn find(&self, query: &T) -> bool
where
T: Eq,
{
if self.data == *query {
return true;
}
for n in self.edges.borrow().iter() {
if let Some(i) = n.upgrade() {
if i.find(query) {
return true;
}
} else {
println!("no strong references to this value so it was dropped")
}
}
return false;
}
}
#[cfg(test)]
mod tests {
use crate::Node;
use std::rc::Rc;
#[test]
fn find_test() {
let n1 = Node::new(1);
let n3 = Node::new(3);
let rc3 = Rc::new(n3);
// the first element in `children` will not be upgradable because
// there is no strong references to it. The second element in
// children has `rc3` as a strong reference so it won't be dropped until
// the test function terminates
let graph = Rc::new(Node::new_with_children(
5,
vec![Rc::downgrade(&Rc::new(n1)), Rc::downgrade(&rc3)],
));
println!("{:?}", graph);
let result = graph.find(&1);
assert_eq!(true, result);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment