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:?}"); }
-
Boxis likestd::unique_ptrin 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
Boxwas not used and we attempted to embed aListdirectly into theList, the compiler would not be able to compute a fixed size for the struct in memory (theListwould be of infinite size). -
Box大小与一般指针相同,并且只会指向堆中的下一个List元素, 因此可以解决这个问题。 -
Remove the
Boxin the List definition and show the compiler error. We get the message "recursive without indirection", because for data recursion, we have to use indirection, aBoxor reference of some kind, instead of storing the value directly. -
Though
Boxlooks likestd::unique_ptrin C++, it cannot be empty/null. This makesBoxone of the types that allow the compiler to optimize storage of some enums (the "niche optimization").