Rust Guide > Documentation > Collections > Box

Introduction

The Box class in Rust provides a way to store data on the heap. It is a smart pointer that allocates memory on the heap and allows multiple copies of the pointer to be created and shared.

Using Box

The Box class is used to create a heap-allocated value. This can be useful for recursive data structures or large values that should not be copied. Here is a simple example:

fn main() {
    let b = Box::new(5);
    println!("b = {}", b);
}
// Output: b = 5

Key Methods

Below are some of the key methods exposed by the Box class:

new

Creates a new Box that contains the given value.

fn main() {
    let b = Box::new(10);
    println!("b = {}", b);
}
// Output: b = 10

deref

Dereferences the Box to access the value it points to.

fn main() {
    let b = Box::new(15);
    let x = *b;
    println!("x = {}", x);
}
// Output: x = 15

drop

Explicitly drops the Box and deallocates the heap memory. This is typically done automatically when the Box goes out of scope.

fn main() {
    let b = Box::new(20);
    drop(b);
    // b is now invalid
}

Example Usage

Example 1: Basic Usage

fn main() {
    let b = Box::new(25);
    println!("b = {}", b);
}
// Output: b = 25

Example 2: Using Box with Structs


struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let point = Box::new(Point { x: 10, y: 20 });
    println!("Point: ({}, {})", point.x, point.y);
}
// Output: Point: (10, 20)

Example 3: Recursive Data Structures


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

fn main() {
    let list = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
    println!("List created.");
}
// Output: List created.

Example 4: Moving Ownership

fn main() {
    let b = Box::new(30);
    let b2 = b;
    println!("b2 = {}", b2);
    // b cannot be used here because its ownership has been moved to b2
}
// Output: b2 = 30

Example 5: Optional Box

fn main() {
    let opt_box: Option<Box<i32>> = Some(Box::new(35));
    if let Some(b) = opt_box {
        println!("b = {}", b);
    }
}
// Output: b = 35

Considerations

  • Using Box can be more efficient for large values or recursive data structures.
  • Dereferencing a Box involves a level of indirection, which may have performance implications.
  • Memory allocated by Box is freed when the Box goes out of scope or is explicitly dropped.

See Also

  • Rc - A reference-counted smart pointer for shared ownership.
  • Arc - An atomic reference-counted smart pointer for shared ownership across threads.
  • Cell - A container for values that allows interior mutability.
  • RefCell - A container for values that allows interior mutability with dynamic borrowing rules.