The Box primitive

Rust has a cool built-in feature called Box<T>. It’s kind of like a pointer, a “smart pointer”.

More specifically, Box<T> is for heap-allocated values that are not known at runtime. It has a known, fixed size.

It looks like this:

fn main() {
    let boxed_value = Box::new(5); // Allocate an integer on the heap
    println!("Boxed value: {}", boxed_value);  // Access it like a normal value
}

Dynamic runtime values

Box<T> can also be used for things where data might be dynamic, or a specific run-time instance of a trait might not be known at compile time.

In this sense, it can be used for polymorphism.

trait Drivable {
    fn drive(&self);
}

struct Car;
impl Drivable for Car {
    fn drive(&self) {
        println!("vroom vroom imacar heh")
    }
}

struct Tractor;
impl Drivable for Tractor {
    fn drive(&self) {
        println!("glug glug ima traktor");
    }
}

fn main() {
    let mut vehicle: Box<dyn Drivable> = Box::new(Tractor);
    vehicle.drive();
    // can later change the value in the box to a Car
}

Recursion

Lastly, another use for box: recursion.

enum List {
    Cons(i32, Box<List>),
    Nil,
}

fn main() {
    let list = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
}

In this example, Box allows you to create a recursive List type by heap-allocating each list node.

end of storey Last modified: