Box<T>
Box
是指向堆上数据的自有指针:
fn main() { let five = Box::new(5); println!("five: {}", *five); }
Box<T>
会实现 Deref<Target = T>
,这意味着您可以直接在 Box<T>
上通过 T
调用相应方法。
Recursive data types or data types with dynamic sizes cannot be stored inline without a pointer indirection. Box
accomplishes that indirection:
#[derive(Debug)] enum List<T> { /// A non-empty list: first element and the rest of the list. Element(T, Box<List<T>>), /// An empty list. Nil, } fn main() { let list: List<i32> = List::Element(1, Box::new(List::Element(2, Box::new(List::Nil)))); println!("{list:?}"); }
-
Box
is likestd::unique_ptr
in C++, except that it's guaranteed to be not null. -
在以下情况下,
Box
可能会很实用:- have a type whose size can't be known at compile time, but the Rust compiler wants to know an exact size.
- 想要转让大量数据的所有权。为避免在堆栈上复制大量数据,请改为将数据存储在
Box
中的堆上,以便仅移动指针。
-
If
Box
was not used and we attempted to embed aList
directly into theList
, the compiler would not be able to compute a fixed size for the struct in memory (theList
would be of infinite size). -
Box
大小与一般指针相同,并且只会指向堆中的下一个List
元素, 因此可以解决这个问题。 -
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, aBox
or reference of some kind, instead of storing the value directly. -
Though
Box
looks likestd::unique_ptr
in C++, it cannot be empty/null. This makesBox
one of the types that allow the compiler to optimize storage of some enums (the "niche optimization").