Rust 标准库中常见的数据类型
Box 智能指针
定义
- 允许将一个值放在堆而不是栈上,留在栈上的是一个指向堆数据的指针
2. Box 是一个指向堆的智能指针,当它超出作用域时,它的析构函数被调用,内部对象被销毁,堆上内存被释放fn main() {
let n = Box::new(100);
println!("n = {}", n);
}
使用
注意:Box 没有运行上的性能损失,但是只在以下场景比默认栈上分配更适用:
- 有一个在编译时未知大小的类型,又想要在需要确切大小的上下文中使用这个类型值
- 递归类型无法在编译时知道具体大小(ConsList)
- 有大量数据并希望在确保数据不被拷贝的情况下转移所有权
希望拥有一个值,只关心它的类型是否实现了特定Trait,而不是其具体类型
场景1: ConsList 每一项包含两个元素:当前项(/结束项)和下一项
ConsList(0, ConsList(1, ConsList(2, Nil)))
``rust // 编译时大小未知,又想要在需要确切大小的上下文中使用这个类型值 // 这里会编译器报错:recursive type
List` has infinite size enum List { Cons(i32, List), Nil, } fn main() { let list = List::Cons(0, List::Cons(1, List::Cons(2, List::Nil))); }
// 使用Box解决报错
enum List {
Cons(i32, Box), // 是一个包含List的地址
Nil,
}
fn main() {
let list = List::Cons(0, Box::new(List::Cons(1, Box::new(List::Cons(2, Box::new( List::Nil))))));
}
- 二叉树、字典树、链表等结构都会用到
<a name="WBfeo"></a>
#### 场景2: 有大量数据并希望在确保数据不被拷贝的情况下转移所有权
```rust
fn main() {
let a = [0; 1024 * 512];
let a_box = Box::new(a); // 把a的数据移到堆上(从栈内存拷贝到堆)
// ... 转移到堆后,再转移所有权就不会有内存拷贝
// let a_box = Box::new([0; 1024 * 512]); // 这一行和上面的两行实现在编译器看来,都没有区别
}