// Recursive type using boxes use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] enum List { Cons(Rc>, Rc), Nil, } struct MyBox(T); impl MyBox { fn new(x: T) -> MyBox { MyBox(x) } } use std::ops::Deref; impl Deref for MyBox { type Target = T; fn deref(&self) -> &T { &self.0 } } struct CustomSmartPointer { data: String, } impl Drop for CustomSmartPointer { fn drop(&mut self) { println!("Dropping CustomSmartPointer with data `{}`!", self.data); } } fn main() { // Storing `i32` value on heap let b = Box::new(5); println!("b = {}", b); use crate::List::{Cons, Nil}; let list = Cons(Rc::new(RefCell::new(1)), Rc::new(Cons(Rc::new(RefCell::new(2)), Rc::new(Cons(Rc::new(RefCell::new(3)), Rc::new(Nil)))))); // Dereferencing let x = 5; let y = &x; assert_eq!(5, x); assert_eq!(5, *y); let x = 5; let y = Box::new(x); assert_eq!(5, x); assert_eq!(5, *y); let x = 5; let y = MyBox::new(x); assert_eq!(5, x); assert_eq!(5, *y); // `*y` is equivalent to `*(y.deref())` fn hello(name: &str) { println!("Hello, {}", name); } // Deref coercion let m = MyBox::new(String::from("Rust")); // `&MyBox` -> `&String` -> `&str` hello(&m); // `m`: MyBox, `*m`: String, `(*m)[..]`: str, `&(*m)[..]`: &str hello(&(*m)[..]); let c = CustomSmartPointer { data: String::from("my stuff"), }; let d = CustomSmartPointer { data: String::from("other stuff"), }; println!("CustomSmartPointer created."); drop(c); println!("CustomSmartPointer dropped before the end of main."); let value = Rc::new(RefCell::new(5)); let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a)); let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a)); *value.borrow_mut() += 10; println!("a after = {:?}", a); println!("b after = {:?}", b); println!("c after = {:?}", c); }