-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Smart Pointers and Advanced Patterns
- Loading branch information
1 parent
c0b3442
commit 9464807
Showing
8 changed files
with
242 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
pub fn run() { | ||
println!("\nAdvanced Pattern Matching Examples:"); | ||
|
||
// Example 1: Pattern matching with guards | ||
pattern_guards(); | ||
|
||
// Example 2: Multiple patterns | ||
multiple_patterns(); | ||
|
||
// Example 3: Destructuring | ||
destructuring_examples(); | ||
} | ||
|
||
fn pattern_guards() { | ||
let number = 4; | ||
|
||
match number { | ||
n @ 1..=5 if n % 2 == 0 => println!("{} is even and between 1 and 5", n), | ||
n @ 1..=5 => println!("{} is odd and between 1 and 5", n), | ||
n if n % 2 == 0 => println!("{} is even", n), | ||
_ => println!("Doesn't match any pattern"), | ||
} | ||
} | ||
|
||
fn multiple_patterns() { | ||
let x = 1; | ||
match x { | ||
1 | 2 | 3 => println!("One, two, or three"), | ||
4..=10 => println!("Four through ten"), | ||
_ => println!("Something else"), | ||
} | ||
} | ||
|
||
fn destructuring_examples() { | ||
// Tuple destructuring | ||
let point = (3, -7); | ||
let (x, y) = point; | ||
println!("Point: x = {}, y = {}", x, y); | ||
|
||
// Struct destructuring | ||
struct Person { | ||
name: String, | ||
age: u32, | ||
} | ||
|
||
let person = Person { | ||
name: String::from("Alice"), | ||
age: 30, | ||
}; | ||
|
||
let Person { name, age } = person; | ||
println!("{} is {} years old", name, age); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use std::mem; | ||
|
||
// Example of recursive type using Box | ||
#[derive(Debug)] | ||
enum List<T> { | ||
Cons(T, Box<List<T>>), | ||
Nil, | ||
} | ||
|
||
pub fn run() { | ||
println!("\nBox Smart Pointer Examples:"); | ||
|
||
// Example 1: Using Box for heap allocation | ||
let b = Box::new(5); | ||
println!("Box contains: {}", b); | ||
|
||
// Example 2: Recursive type with Box | ||
let list = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); | ||
println!("List: {:?}", list); | ||
|
||
// Example 3: Large data on heap | ||
let large_data = Box::new([0; 1000]); | ||
println!("Large array size: {} bytes", mem::size_of_val(&*large_data)); | ||
|
||
// Example 4: Box for trait objects | ||
let trait_object: Box<dyn ToString> = Box::new(42); | ||
println!("Trait object to string: {}", trait_object.to_string()); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use std::ops::Deref; | ||
use std::ops::DerefMut; | ||
|
||
// Custom smart pointer | ||
struct MyBox<T>(T); | ||
|
||
impl<T> MyBox<T> { | ||
fn new(x: T) -> MyBox<T> { | ||
MyBox(x) | ||
} | ||
} | ||
|
||
// Implementing Deref | ||
impl<T> Deref for MyBox<T> { | ||
type Target = T; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
// Implementing DerefMut | ||
impl<T> DerefMut for MyBox<T> { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
pub fn run() { | ||
println!("\nCustom Smart Pointer Examples:"); | ||
|
||
// Using our custom smart pointer | ||
let x = 5; | ||
let y = MyBox::new(x); | ||
|
||
println!("Original value: {}", x); | ||
println!("Value through MyBox: {}", *y); | ||
|
||
// Using with mutable reference | ||
let mut z = MyBox::new(String::from("Hello")); | ||
z.push_str(" World!"); | ||
println!("Mutable MyBox: {}", *z); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
pub mod box_pointer; | ||
pub mod rc_pointer; | ||
pub mod ref_cell; | ||
pub mod weak_references; | ||
pub mod advanced_patterns; | ||
pub mod custom_smart_pointer; | ||
|
||
pub fn run() { | ||
println!("Days 31-33: Smart Pointers and Advanced Patterns"); | ||
box_pointer::run(); | ||
rc_pointer::run(); | ||
ref_cell::run(); | ||
weak_references::run(); | ||
advanced_patterns::run(); | ||
custom_smart_pointer::run(); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use std::rc::Rc; | ||
|
||
#[derive(Debug)] | ||
struct Node { | ||
value: i32, | ||
next: Option<Rc<Node>>, | ||
} | ||
|
||
pub fn run() { | ||
println!("\nRc Smart Pointer Examples:"); | ||
|
||
// Example 1: Basic Rc usage | ||
let value = Rc::new(42); | ||
let value2 = Rc::clone(&value); | ||
println!("Reference count: {}", Rc::strong_count(&value)); | ||
println!("Values: {} {}", value, value2); | ||
|
||
// Example 2: Shared ownership in a list | ||
let node3 = Rc::new(Node { | ||
value: 3, | ||
next: None, | ||
}); | ||
|
||
let node2 = Rc::new(Node { | ||
value: 2, | ||
next: Some(Rc::clone(&node3)), | ||
}); | ||
|
||
let node1 = Node { | ||
value: 1, | ||
next: Some(Rc::clone(&node2)), | ||
}; | ||
|
||
println!("Node 1: {:?}", node1); | ||
println!("Reference count of node2: {}", Rc::strong_count(&node2)); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use std::cell::RefCell; | ||
|
||
pub fn run() { | ||
println!("\nRefCell Examples:"); | ||
|
||
// Example 1: Basic RefCell usage | ||
let data = RefCell::new(42); | ||
println!("Initial value: {:?}", data); | ||
|
||
// Mutate through RefCell | ||
*data.borrow_mut() = 100; | ||
println!("After mutation: {:?}", data); | ||
|
||
// Example 2: Multiple borrows | ||
{ | ||
let reading = data.borrow(); | ||
println!("First borrow: {}", *reading); | ||
|
||
// This would panic - uncomment to see: | ||
// let writing = data.borrow_mut(); // Already borrowed | ||
} | ||
|
||
// Example 3: RefCell with a more complex type | ||
let list = RefCell::new(vec![1, 2, 3]); | ||
list.borrow_mut().push(4); | ||
println!("Vector: {:?}", list.borrow()); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use std::rc::{Rc, Weak}; | ||
use std::cell::RefCell; | ||
|
||
#[derive(Debug)] | ||
struct Node { | ||
value: i32, | ||
parent: RefCell<Weak<Node>>, | ||
children: RefCell<Vec<Rc<Node>>>, | ||
} | ||
|
||
pub fn run() { | ||
println!("\nWeak Reference Examples:"); | ||
|
||
// Create a tree structure with weak parent references | ||
let leaf = Rc::new(Node { | ||
value: 3, | ||
parent: RefCell::new(Weak::new()), | ||
children: RefCell::new(vec![]), | ||
}); | ||
|
||
println!("Leaf parent = {:?}", leaf.parent.borrow().upgrade()); | ||
|
||
let branch = Rc::new(Node { | ||
value: 5, | ||
parent: RefCell::new(Weak::new()), | ||
children: RefCell::new(vec![Rc::clone(&leaf)]), | ||
}); | ||
|
||
*leaf.parent.borrow_mut() = Rc::downgrade(&branch); | ||
|
||
println!("Leaf parent = {:?}", leaf.parent.borrow().upgrade()); | ||
println!("Branch strong count = {}", Rc::strong_count(&branch)); | ||
println!("Branch weak count = {}", Rc::weak_count(&branch)); | ||
} |
This file contains 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