Box
- When you have a type whose size can’t be known at compile time and you want to use a value of that type in a context that requires an exact size (recursive type)
- When you have a large amount of data and you want to transfer ownership but ensure the data won’t be copied when you do so
- When you want to own a value and you care only that it’s a type that implements a particular trait rather than being of a specific type (trait object)
// when b goes out of scope, the deallocation happens both for the box(sotred on the stack) // and the data it points to (stored on the heap) fn main() { let b = Box::new(5); println!("{b}"); }
Box usage in recursive type
#[derive(Debug)] enum List<T> { Nil, Cons(T, Box<List<T>>) } fn main() { use crate::List::{Nil, Cons}; let l = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil)))))); dbg!(l); }
The Box
type is a smart pointer because it implements the Deref trait, which allows Box values to be treated like references. When a Box value goes out of scope, the heap data that the box is pointing to is cleaned up as well because of the Drop trait implementation.