Skip to content

Commit 9464807

Browse files
committed
Smart Pointers and Advanced Patterns
1 parent c0b3442 commit 9464807

8 files changed

Lines changed: 242 additions & 1 deletion

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
pub fn run() {
2+
println!("\nAdvanced Pattern Matching Examples:");
3+
4+
// Example 1: Pattern matching with guards
5+
pattern_guards();
6+
7+
// Example 2: Multiple patterns
8+
multiple_patterns();
9+
10+
// Example 3: Destructuring
11+
destructuring_examples();
12+
}
13+
14+
fn pattern_guards() {
15+
let number = 4;
16+
17+
match number {
18+
n @ 1..=5 if n % 2 == 0 => println!("{} is even and between 1 and 5", n),
19+
n @ 1..=5 => println!("{} is odd and between 1 and 5", n),
20+
n if n % 2 == 0 => println!("{} is even", n),
21+
_ => println!("Doesn't match any pattern"),
22+
}
23+
}
24+
25+
fn multiple_patterns() {
26+
let x = 1;
27+
match x {
28+
1 | 2 | 3 => println!("One, two, or three"),
29+
4..=10 => println!("Four through ten"),
30+
_ => println!("Something else"),
31+
}
32+
}
33+
34+
fn destructuring_examples() {
35+
// Tuple destructuring
36+
let point = (3, -7);
37+
let (x, y) = point;
38+
println!("Point: x = {}, y = {}", x, y);
39+
40+
// Struct destructuring
41+
struct Person {
42+
name: String,
43+
age: u32,
44+
}
45+
46+
let person = Person {
47+
name: String::from("Alice"),
48+
age: 30,
49+
};
50+
51+
let Person { name, age } = person;
52+
println!("{} is {} years old", name, age);
53+
}

src/day31_to_day33/box_pointer.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use std::mem;
2+
3+
// Example of recursive type using Box
4+
#[derive(Debug)]
5+
enum List<T> {
6+
Cons(T, Box<List<T>>),
7+
Nil,
8+
}
9+
10+
pub fn run() {
11+
println!("\nBox Smart Pointer Examples:");
12+
13+
// Example 1: Using Box for heap allocation
14+
let b = Box::new(5);
15+
println!("Box contains: {}", b);
16+
17+
// Example 2: Recursive type with Box
18+
let list = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
19+
println!("List: {:?}", list);
20+
21+
// Example 3: Large data on heap
22+
let large_data = Box::new([0; 1000]);
23+
println!("Large array size: {} bytes", mem::size_of_val(&*large_data));
24+
25+
// Example 4: Box for trait objects
26+
let trait_object: Box<dyn ToString> = Box::new(42);
27+
println!("Trait object to string: {}", trait_object.to_string());
28+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use std::ops::Deref;
2+
use std::ops::DerefMut;
3+
4+
// Custom smart pointer
5+
struct MyBox<T>(T);
6+
7+
impl<T> MyBox<T> {
8+
fn new(x: T) -> MyBox<T> {
9+
MyBox(x)
10+
}
11+
}
12+
13+
// Implementing Deref
14+
impl<T> Deref for MyBox<T> {
15+
type Target = T;
16+
17+
fn deref(&self) -> &Self::Target {
18+
&self.0
19+
}
20+
}
21+
22+
// Implementing DerefMut
23+
impl<T> DerefMut for MyBox<T> {
24+
fn deref_mut(&mut self) -> &mut Self::Target {
25+
&mut self.0
26+
}
27+
}
28+
29+
pub fn run() {
30+
println!("\nCustom Smart Pointer Examples:");
31+
32+
// Using our custom smart pointer
33+
let x = 5;
34+
let y = MyBox::new(x);
35+
36+
println!("Original value: {}", x);
37+
println!("Value through MyBox: {}", *y);
38+
39+
// Using with mutable reference
40+
let mut z = MyBox::new(String::from("Hello"));
41+
z.push_str(" World!");
42+
println!("Mutable MyBox: {}", *z);
43+
}

src/day31_to_day33/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pub mod box_pointer;
2+
pub mod rc_pointer;
3+
pub mod ref_cell;
4+
pub mod weak_references;
5+
pub mod advanced_patterns;
6+
pub mod custom_smart_pointer;
7+
8+
pub fn run() {
9+
println!("Days 31-33: Smart Pointers and Advanced Patterns");
10+
box_pointer::run();
11+
rc_pointer::run();
12+
ref_cell::run();
13+
weak_references::run();
14+
advanced_patterns::run();
15+
custom_smart_pointer::run();
16+
}

src/day31_to_day33/rc_pointer.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use std::rc::Rc;
2+
3+
#[derive(Debug)]
4+
struct Node {
5+
value: i32,
6+
next: Option<Rc<Node>>,
7+
}
8+
9+
pub fn run() {
10+
println!("\nRc Smart Pointer Examples:");
11+
12+
// Example 1: Basic Rc usage
13+
let value = Rc::new(42);
14+
let value2 = Rc::clone(&value);
15+
println!("Reference count: {}", Rc::strong_count(&value));
16+
println!("Values: {} {}", value, value2);
17+
18+
// Example 2: Shared ownership in a list
19+
let node3 = Rc::new(Node {
20+
value: 3,
21+
next: None,
22+
});
23+
24+
let node2 = Rc::new(Node {
25+
value: 2,
26+
next: Some(Rc::clone(&node3)),
27+
});
28+
29+
let node1 = Node {
30+
value: 1,
31+
next: Some(Rc::clone(&node2)),
32+
};
33+
34+
println!("Node 1: {:?}", node1);
35+
println!("Reference count of node2: {}", Rc::strong_count(&node2));
36+
}

src/day31_to_day33/ref_cell.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use std::cell::RefCell;
2+
3+
pub fn run() {
4+
println!("\nRefCell Examples:");
5+
6+
// Example 1: Basic RefCell usage
7+
let data = RefCell::new(42);
8+
println!("Initial value: {:?}", data);
9+
10+
// Mutate through RefCell
11+
*data.borrow_mut() = 100;
12+
println!("After mutation: {:?}", data);
13+
14+
// Example 2: Multiple borrows
15+
{
16+
let reading = data.borrow();
17+
println!("First borrow: {}", *reading);
18+
19+
// This would panic - uncomment to see:
20+
// let writing = data.borrow_mut(); // Already borrowed
21+
}
22+
23+
// Example 3: RefCell with a more complex type
24+
let list = RefCell::new(vec![1, 2, 3]);
25+
list.borrow_mut().push(4);
26+
println!("Vector: {:?}", list.borrow());
27+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use std::rc::{Rc, Weak};
2+
use std::cell::RefCell;
3+
4+
#[derive(Debug)]
5+
struct Node {
6+
value: i32,
7+
parent: RefCell<Weak<Node>>,
8+
children: RefCell<Vec<Rc<Node>>>,
9+
}
10+
11+
pub fn run() {
12+
println!("\nWeak Reference Examples:");
13+
14+
// Create a tree structure with weak parent references
15+
let leaf = Rc::new(Node {
16+
value: 3,
17+
parent: RefCell::new(Weak::new()),
18+
children: RefCell::new(vec![]),
19+
});
20+
21+
println!("Leaf parent = {:?}", leaf.parent.borrow().upgrade());
22+
23+
let branch = Rc::new(Node {
24+
value: 5,
25+
parent: RefCell::new(Weak::new()),
26+
children: RefCell::new(vec![Rc::clone(&leaf)]),
27+
});
28+
29+
*leaf.parent.borrow_mut() = Rc::downgrade(&branch);
30+
31+
println!("Leaf parent = {:?}", leaf.parent.borrow().upgrade());
32+
println!("Branch strong count = {}", Rc::strong_count(&branch));
33+
println!("Branch weak count = {}", Rc::weak_count(&branch));
34+
}

src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ pub mod day25_to_day27;
2828
//Day 28 to day 30
2929
pub mod day28_to_day30;
3030

31+
//Day 31 to day 33
32+
pub mod day31_to_day33;
33+
3134
fn main() {
3235
// day01_to_day03::run();
3336
// day04_to_day06::run();
@@ -38,6 +41,7 @@ fn main() {
3841
// day19_to_day21::run();
3942
// day22_to_day24::run();
4043
// day25_to_day27::run();
41-
day28_to_day30::run();
44+
// day28_to_day30::run();
45+
day31_to_day33::run();
4246

4347
}

0 commit comments

Comments
 (0)