Skip to content

Commit e8c937d

Browse files
committed
code for 0x10 Smart Pointers
1 parent af4cbbe commit e8c937d

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Node:
2+
printed = set()
3+
4+
def __init__(self, value):
5+
self.parent = None
6+
self.left = None
7+
self.right = None
8+
self.value = value
9+
10+
def __repr__(self):
11+
try:
12+
if id(self) in self.printed:
13+
return f"-"
14+
self.printed.add(id(self))
15+
spaces = " " * len(self.printed)
16+
s = f"Node\n{spaces}{spaces}parent: {self.parent}, left: {self.left}, right: {self.right}, v: {self.value}\n"
17+
return s
18+
except RecursionError:
19+
return "-"
20+
21+
22+
if __name__ == '__main__':
23+
root = Node(0)
24+
node = Node(1)
25+
node.parent = root
26+
root.left = node
27+
node2 = Node(2)
28+
root.parent = node2
29+
30+
print("Root:", root)
31+
Node.printed = set()
32+
print("Parent left:", root.left.parent.value)
33+
Node.printed = set()
34+
print("ids: {} {}".format(id(node2), id(root.parent)))
35+
del node2
36+
#root.parent = None
37+
print("Parent: ", root.parent)

10_smart_pointers/python/rc.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import sys
2+
3+
if __name__ == "__main__":
4+
rc_examples = "Rc examples"
5+
print("refcount of rc_examples", sys.getrefcount(rc_examples))
6+
7+
def scope():
8+
print("rc created")
9+
10+
rc_a = rc_examples
11+
print("refcount of rc_a", sys.getrefcount(rc_a))
12+
13+
def subscope():
14+
rc_b = rc_a
15+
print("refcount of rc_b", sys.getrefcount(rc_b))
16+
print("refcount of rc_a", sys.getrefcount(rc_a))
17+
print("refcount of rc_examples", sys.getrefcount(rc_examples))
18+
19+
subscope()
20+
print("refcount of rc_examples after del rc_b", sys.getrefcount(rc_examples))
21+
22+
scope()
23+
print("refcount of rc_examples after del rc_a", sys.getrefcount(rc_examples))

10_smart_pointers/rust/bintree.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/// for illustration purposes only, do not use IRL!
2+
use std::cell::RefCell; // a "runtime borrow-checker"
3+
use std::fmt::Debug;
4+
use std::rc::{Rc, Weak};
5+
6+
#[derive(Debug)]
7+
struct Node<T> {
8+
parent: Option<Weak<RefCell<Node<T>>>>,
9+
left: Option<Rc<RefCell<Node<T>>>>,
10+
right: Option<Rc<RefCell<Node<T>>>>,
11+
value: T,
12+
}
13+
14+
impl<T: Debug> Node<T> {
15+
fn new(value: T) -> Node<T> {
16+
Node {
17+
parent: None,
18+
left: None,
19+
right: None,
20+
value,
21+
}
22+
}
23+
24+
fn print_parent(&self) {
25+
if let Some(parent) = &self.parent {
26+
if let Some(parent) = parent.upgrade() {
27+
println!("Parent: {:?}", parent.borrow().value);
28+
} else {
29+
println!("Parent: no more parent");
30+
}
31+
} else {
32+
println!("Parent: None");
33+
}
34+
}
35+
}
36+
37+
fn main() {
38+
let root = Rc::new(RefCell::new(Node::new(0)));
39+
let node = Rc::new(RefCell::new(Node::new(1)));
40+
node.borrow_mut().parent = Some(Rc::downgrade(&root));
41+
42+
let node2 = Rc::new(RefCell::new(Node::new(2)));
43+
44+
root.borrow_mut().parent = Some(Rc::downgrade(&node2));
45+
root.borrow_mut().left = Some(node);
46+
47+
println!("Root: {:?}", *root.borrow());
48+
if let Some(left) = &root.borrow().left {
49+
&left.borrow().print_parent();
50+
};
51+
&root.borrow().print_parent();
52+
drop(node2);
53+
&root.borrow().print_parent();
54+
}

10_smart_pointers/rust/rc.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::rc::Rc;
2+
3+
fn main() {
4+
let rc_examples = "Rc examples".to_string();
5+
// new scope
6+
{
7+
println!("--- rc_a is created ---");
8+
9+
let rc_a: Rc<String> = Rc::new(rc_examples);
10+
println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a));
11+
12+
// one more scope
13+
{
14+
let rc_b: Rc<String> = Rc::clone(&rc_a);
15+
println!("Ref Count of rc_b: {}", Rc::strong_count(&rc_b));
16+
println!("Ref Count of rc_a: {}", Rc::strong_count(&rc_a));
17+
18+
// Two `Rc`s are equal if their inner values are equal
19+
println!("rc_a and rc_b are equal: {}", rc_a.eq(&rc_b));
20+
21+
// We can use methods of a value directly
22+
println!("Length of the value inside rc_a: {}", rc_a.len());
23+
println!("Value of rc_b: {}", rc_b);
24+
}
25+
26+
println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a));
27+
28+
println!("--- rc_a is dropped out of scope ---");
29+
}
30+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use std::error;
2+
use std::rc::Rc;
3+
4+
type Result<T> = std::result::Result<T, Box<dyn error::Error>>;
5+
6+
struct List {
7+
next: Option<Box<List>>,
8+
value: i32,
9+
}
10+
11+
fn main() -> Result<()> {
12+
let a = Box::new(5);
13+
println!("deref of box {:?} yields {}", a, *a);
14+
let mut l = List {
15+
next: None,
16+
value: 1,
17+
};
18+
l.next = Some(Box::new(List {
19+
next: None,
20+
value: 2,
21+
}));
22+
println!("list value {}", l.value);
23+
24+
let b = Rc::new(*a);
25+
let _c = Rc::clone(&b); // increase reference count (cheap)
26+
println!("{} refcount: {}", &b, Rc::strong_count(&b));
27+
// if b is not a Rc type this is potentially deep-copying (expensive)
28+
// avoid this notation when doing refcount clones
29+
let _d = b.clone();
30+
println!("{} refcount: {}", &b, Rc::strong_count(&b));
31+
Ok(())
32+
}

0 commit comments

Comments
 (0)