Those familiar with c++ definitely know
unique_ptr , and Rust also has smart pointers
RefCell , etc. This article shares the underlying implementation of
Box<T> allocates space on the heap, stores the T value, and returns the corresponding pointer. Also
Box implements trait
Deref dereference and
Drop destructor to automatically free space when
Box leaves the scope.
Getting Started Example
Example from the rust book, without the print statement for demonstration purposes.
Assign the variable 0x11223344 to the heap, the so-called boxing, which java students are surely familiar with. Let’s mount docker, and use rust-gdb to see the assembly implementation.
The key point is two,
alloc::alloc::exchange_malloc allocates memory space on the heap and then stores
0x11223344 to the address of this malloc
At the end of the function, the address is passed to
core::ptr::drop_in_place to be freed, because the compiler knows that the type is
alloc::boxed::Box<i32> , and will drop the corresponding drop function with
Looking at this example alone,
Box is not mysterious, it corresponds to the assembly implementation and is no different from a normal pointer, all constraints are compile-time behavior.
This example boxes a string, which is not necessary because
String is, broadly speaking, a smart pointer. This example will report an error.
*x is dereferenced, it corresponds to
String, and when it is assigned to y, it executes move semantics, and the ownership is gone, so the subsequent println cannot print x.
You can take an immutable reference to a string to fix it.
Above is the definition of
Box, which can be seen as a tuple structure with two generic parameters:
T for an arbitrary type and
A for a memory allocator. In the standard library
A is the Gloal default value. Where
T has a generic constraint
?Sized , indicating that the type size may or may not be known at compile time.
This is the
Drop implementation, as stated in the source code, implemented by the compiler.
Deref to define dereference behavior, and
DerefMut to mutable dereferences. So
*x corresponds to the operation
The official website mentions the following three scenarios, essentially
Box is not very different from a normal pointer, so it is not as useful as
- When the type does not know the size at compile time, but the code scenario also requires confirming the type size.
- When you have a lot of data and need to move ownership, and don’t want to copy the data.
- trait objects, or dyn dynamic distribution is commonly used to store different types in a collection, or parameters specify different types. s The official website mentions an implementation of a linked table.
The above code does not work, and the reason is simple: it is a recursive definition. It doesn’t work with c code either, we usually have to define next type as a pointer.
The solution given by the official website is to turn next into a pointer
Box<List> , which is common sense, nothing to say.