Skip to main content
Glama
smart_pointers.rs6.94 kB
// smart_pointers.rs - Demonstrates Rust smart pointers use std::cell::{Cell, RefCell}; use std::rc::{Rc, Weak}; use std::sync::Arc; // Box - heap allocation /// Basic Box usage pub fn box_example() -> Box<i32> { Box::new(42) } /// Recursive type with Box #[derive(Debug)] pub enum List { Cons(i32, Box<List>), Nil, } impl List { pub fn new() -> Self { List::Nil } pub fn prepend(self, value: i32) -> Self { List::Cons(value, Box::new(self)) } pub fn len(&self) -> usize { match self { List::Cons(_, tail) => 1 + tail.len(), List::Nil => 0, } } } /// Box with trait object pub trait Shape { fn area(&self) -> f64; } pub struct Circle { radius: f64, } pub struct Rectangle { width: f64, height: f64, } impl Shape for Circle { fn area(&self) -> f64 { std::f64::consts::PI * self.radius * self.radius } } impl Shape for Rectangle { fn area(&self) -> f64 { self.width * self.height } } pub fn create_shapes() -> Vec<Box<dyn Shape>> { vec![ Box::new(Circle { radius: 5.0 }), Box::new(Rectangle { width: 10.0, height: 5.0, }), ] } // Rc - reference counting /// Shared ownership with Rc pub fn rc_example() { let data = Rc::new(vec![1, 2, 3, 4, 5]); let data2 = Rc::clone(&data); let data3 = Rc::clone(&data); println!("Data: {:?}, count: {}", data, Rc::strong_count(&data)); } /// Graph structure with Rc #[derive(Debug)] pub struct Node { value: i32, children: Vec<Rc<Node>>, } impl Node { pub fn new(value: i32) -> Rc<Self> { Rc::new(Self { value, children: Vec::new(), }) } pub fn value(&self) -> i32 { self.value } } /// Tree with Rc and Weak #[derive(Debug)] pub struct TreeNode { value: i32, parent: RefCell<Weak<TreeNode>>, children: RefCell<Vec<Rc<TreeNode>>>, } impl TreeNode { pub fn new(value: i32) -> Rc<Self> { Rc::new(Self { value, parent: RefCell::new(Weak::new()), children: RefCell::new(Vec::new()), }) } pub fn add_child(self: &Rc<Self>, child: Rc<TreeNode>) { *child.parent.borrow_mut() = Rc::downgrade(self); self.children.borrow_mut().push(child); } } // RefCell - interior mutability /// RefCell for interior mutability pub struct MockMessenger { pub sent_messages: RefCell<Vec<String>>, } impl MockMessenger { pub fn new() -> Self { Self { sent_messages: RefCell::new(Vec::new()), } } pub fn send(&self, message: &str) { self.sent_messages.borrow_mut().push(message.to_string()); } pub fn message_count(&self) -> usize { self.sent_messages.borrow().len() } } /// Combining Rc and RefCell pub struct SharedData { data: Rc<RefCell<Vec<i32>>>, } impl SharedData { pub fn new() -> Self { Self { data: Rc::new(RefCell::new(Vec::new())), } } pub fn add(&self, value: i32) { self.data.borrow_mut().push(value); } pub fn get(&self, index: usize) -> Option<i32> { self.data.borrow().get(index).copied() } pub fn clone_ref(&self) -> SharedData { SharedData { data: Rc::clone(&self.data), } } } // Cell - for Copy types pub struct CellExample { value: Cell<i32>, } impl CellExample { pub fn new(value: i32) -> Self { Self { value: Cell::new(value), } } pub fn get(&self) -> i32 { self.value.get() } pub fn set(&self, value: i32) { self.value.set(value); } pub fn increment(&self) { let current = self.value.get(); self.value.set(current + 1); } } // Weak references pub fn weak_reference_example() { let strong = Rc::new(42); let weak = Rc::downgrade(&strong); println!("Strong count: {}", Rc::strong_count(&strong)); println!("Weak count: {}", Rc::weak_count(&strong)); match weak.upgrade() { Some(value) => println!("Value: {}", value), None => println!("Value has been dropped"), } } // Custom smart pointer pub struct MyBox<T> { value: T, } impl<T> MyBox<T> { pub fn new(value: T) -> Self { Self { value } } } impl<T> std::ops::Deref for MyBox<T> { type Target = T; fn deref(&self) -> &Self::Target { &self.value } } impl<T> std::ops::DerefMut for MyBox<T> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.value } } // Drop trait pub struct CustomDrop { data: String, } impl CustomDrop { pub fn new(data: String) -> Self { println!("Creating CustomDrop with: {}", data); Self { data } } } impl Drop for CustomDrop { fn drop(&mut self) { println!("Dropping CustomDrop with: {}", self.data); } } // Arc for thread-safe reference counting use std::sync::Mutex; use std::thread; pub fn arc_example() { let data = Arc::new(Mutex::new(vec![1, 2, 3])); let mut handles = vec![]; for i in 0..3 { let data = Arc::clone(&data); let handle = thread::spawn(move || { let mut data = data.lock().unwrap(); data.push(i); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } println!("Result: {:?}", data.lock().unwrap()); } // Cow - Clone on Write use std::borrow::Cow; pub fn cow_example(input: &str) -> Cow<str> { if input.contains(' ') { Cow::Owned(input.replace(' ', "_")) } else { Cow::Borrowed(input) } } pub fn cow_modify(mut data: Cow<[i32]>) -> Cow<[i32]> { data.to_mut().push(4); data } #[cfg(test)] mod tests { use super::*; #[test] fn test_list() { let list = List::new().prepend(3).prepend(2).prepend(1); assert_eq!(list.len(), 3); } #[test] fn test_shared_data() { let data = SharedData::new(); let data2 = data.clone_ref(); data.add(1); data2.add(2); assert_eq!(data.get(0), Some(1)); assert_eq!(data.get(1), Some(2)); assert_eq!(data2.get(0), Some(1)); } #[test] fn test_cell() { let cell = CellExample::new(5); assert_eq!(cell.get(), 5); cell.increment(); assert_eq!(cell.get(), 6); } #[test] fn test_mock_messenger() { let messenger = MockMessenger::new(); messenger.send("hello"); messenger.send("world"); assert_eq!(messenger.message_count(), 2); } #[test] fn test_cow() { let borrowed = cow_example("hello"); assert!(matches!(borrowed, Cow::Borrowed(_))); let owned = cow_example("hello world"); assert!(matches!(owned, Cow::Owned(_))); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Shashankss1205/CodeGraphContext'

If you have feedback or need assistance with the MCP directory API, please join our Discord server