• Box

Box

Box is an owned pointer to data on the heap:

1. ```
   fn main() {
   ```
2. ```
       let five = Box::new(5);
   ```
3. ```
       println!("five: {}", *five);
   ```
4. ```
   }
   ```

20.1. Box<T> - 图1

Box<T> implements Deref<Target = T>, which means that you can call methods from T directly on a Box.

Recursive data types or data types with dynamic sizes cannot be stored inline without a pointer indirection. Box accomplishes that indirection:

1. ```
   #[derive(Debug)]
   ```
2. ```
   enum List&lt;T> {
   ```
3. ```
       /// A non-empty list: first element and the rest of the list.
   ```
4. ```
       Element(T, Box&lt;List&lt;T>>),
   ```
5. ```
       /// An empty list.
   ```
6. ```
       Nil,
   ```
7. ```
   }
   ```

9. ```
   fn main() {
   ```
10. ```
        let list: List&lt;i32> =
    ```
11. ```
            List::Element(1, Box::new(List::Element(2, Box::new(List::Nil))));
    ```
12. ```
        println!("{list:?}");
    ```
13. ```
    }
    ```

20.1. Box<T> - 图2

This slide should take about 8 minutes.

  • Box is like std::unique_ptr in C++, except that it’s guaranteed to be not null.
  • A Box can be useful when you:

  • have a type whose size can’t be known at compile time, but the Rust compiler wants to know an exact size.

  • want to transfer ownership of a large amount of data. To avoid copying large amounts of data on the stack, instead store the data on the heap in a Box so only the pointer is moved.
  • If Box was not used and we attempted to embed a List directly into the List, the compiler would not be able to compute a fixed size for the struct in memory (the List would be of infinite size).
  • Box solves this problem as it has the same size as a regular pointer and just points at the next element of the List in the heap.
  • Remove the Box in the List definition and show the compiler error. We get the message “recursive without indirection”, because for data recursion, we have to use indirection, a Box or reference of some kind, instead of storing the value directly.
  • Though Box looks like std::unique_ptr in C++, it cannot be empty/null. This makes Box one of the types that allow the compiler to optimize storage of some enums (the “niche optimization”).