Rust 标准库中常见的数据类型

常见的数据类型 - 图1

Box 智能指针

定义

  1. 允许将一个值放在堆而不是栈上,留在栈上的是一个指向堆数据的指针
    2. Box 是一个指向堆的智能指针,当它超出作用域时,它的析构函数被调用,内部对象被销毁,堆上内存被释放
    1. fn main() {
    2. let n = Box::new(100);
    3. println!("n = {}", n);
    4. }

    使用

    注意:Box 没有运行上的性能损失,但是只在以下场景比默认栈上分配更适用:

  • 有一个在编译时未知大小的类型,又想要在需要确切大小的上下文中使用这个类型值
    • 递归类型无法在编译时知道具体大小(ConsList)
  • 有大量数据并希望在确保数据不被拷贝的情况下转移所有权
  • 希望拥有一个值,只关心它的类型是否实现了特定Trait,而不是其具体类型

    场景1: ConsList 每一项包含两个元素:当前项(/结束项)和下一项

  • ConsList(0, ConsList(1, ConsList(2, Nil))) ``rust // 编译时大小未知,又想要在需要确切大小的上下文中使用这个类型值 // 这里会编译器报错:recursive typeList` 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)))))); }

  1. - 二叉树、字典树、链表等结构都会用到
  2. <a name="WBfeo"></a>
  3. #### 场景2: 有大量数据并希望在确保数据不被拷贝的情况下转移所有权
  4. ```rust
  5. fn main() {
  6. let a = [0; 1024 * 512];
  7. let a_box = Box::new(a); // 把a的数据移到堆上(从栈内存拷贝到堆)
  8. // ... 转移到堆后,再转移所有权就不会有内存拷贝
  9. // let a_box = Box::new([0; 1024 * 512]); // 这一行和上面的两行实现在编译器看来,都没有区别
  10. }

场景3: 只关心一个值的类型是否实现了特定 Trait,而不是它的具体类型