3.1 `Box<T>`
01-
Box<T> — Comprehensive Rust2 分钟阅读
译文 · 基于 Comprehensive Rust
原文链接: https://google.github.io/comprehensive-rust/smart-pointers/box.html
3.1 Box<T>
Box 是指向堆上数据的拥有型指针:
| |
Stack Heap
.- - - - - - -. .- - - - - - -.
: : : :
: five : : :
: +-----+ : : +-----+ :
: | o---|---+-----+-->| 5 | :
: +-----+ : : +-----+ :
: : : :
: : : :
`- - - - - - -' `- - - - - - -'
Box<T> 实现了 Deref<Target = T>,因此你可以
直接在 Box<T> 上调用 T 的方法。
递归数据类型或大小动态的数据类型,若不通过指针间接存储就无法内联存放。Box 提供了这种间接:
| |
Stack Heap
.- - - - - - - - - - - - - - . .- - - - - - - - - - - - - - - - - - - - - - - - -.
: : : :
: list : : :
: +---------+----+----+ : : +---------+----+----+ +------+----+----+ :
: | Element | 1 | o--+----+-----+--->| Element | 2 | o--+--->| Nil | // | // | :
: +---------+----+----+ : : +---------+----+----+ +------+----+----+ :
: : : :
: : : :
'- - - - - - - - - - - - - - ' '- - - - - - - - - - - - - - - - - - - - - - - - -'
Box类似 C++ 的std::unique_ptr,但保证不为空。
Box在以下情况很有用:
- 类型的大小在编译期无法知道,但 Rust 编译器需要确切大小。
- 想转移大量数据的所有权。为避免在栈上拷贝大量数据,把数据放在堆上的
Box中,这样移动的只是指针。若不用
Box、试图把List直接嵌入List,编译器将无法为该结构计算出固定内存大小(List会变成无限大小)。
Box解决了这个问题:它与普通指针大小相同,只是指向堆上List的下一个元素。去掉
List定义中的Box并展示编译错误。会得到「recursive without indirection」之类的信息,因为数据递归必须使用间接——某种Box或引用——而不能直接存储值。尽管
Box看起来像 C++ 的std::unique_ptr,它不能为空/null。这使得Box成为允许编译器优化某些枚举存储的类型之一(「niche optimization」)。