📜  Rust – 盒子智能指针

📅  最后修改于: 2022-05-13 01:54:52.766000             🧑  作者: Mango

锈 - 盒子智能指针

Box 允许我们将数据存储在堆中,这与 Rust 存储为堆栈的默认方案相反。

Box主要用于:

  • 用于为变量动态分配内存。
  • 当有很多数据需要转移所有权并且我们不希望它们被复制时。

让我们创建一个盒子来在堆中存储 i32 值。

例子:

Rust
fn main() {
    let num = Box::new(4);
    println!("num = {}", num);
}


Rust
enum List {
    Cons(i32, List),
    Nil,
}
use crate::List::{Cons, Nil};
  
fn main() {
    let list = Cons(1, Cons(2, Cons(3, Nil)));
}


Rust
// for printing complex data types
#[derive(Debug)] 
enum List {
    Cons(i32, Box),
    Nil,
}
  
use crate::List::{Cons, Nil};
  
fn main() {
    let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
    println!("{:?}",list)
}


输出:

num = 4

使用 Box 作为递归类型:

我们将使用一个缺点列表来创建一个值列表。 cons list 接受两个值,第一个是当前值,另一个是下一个值,它执行对 cons函数的递归调用以生成一个列表,其中递归调用的基本条件是 Nil。

例子:

enum List {
    Cons(i32, List),
    Nil,
}
use crate::List::{Cons, Nil};
  
fn main() {
    let list = Cons(1, Cons(2, Cons(3, Nil)));
}

它不会编译,因为在编译之前无法确定 List 变量大小。

输出:

 rustc -o main main.rs
error[E0072]: recursive type `List` has infinite size
 --> main.rs:1:1
  |
1 | enum List {
  | ^^^^^^^^^ recursive type has infinite size
2 |     Cons(i32, List),
  |               ---- recursive without indirection
  |
  = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable

error[E0391]: cycle detected when processing `List`
 --> main.rs:1:1
  |
1 | enum List {
  | ^^^^^^^^^
  |
  = note: ...which again requires processing `List`, completing the cycle
  = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, def_id: None }, value

有一个错误告诉 List 具有无限大小,因为编译器在编译期间无法确定 List 的大小。所以我们将使用指向列表的指针而不是列表本身来克服这个错误。由于指针的大小是固定的,而与它指向的数据类型无关,因此编译器可以在编译期间确定其大小。让我们看看这个使用 Box 的实现。

例子:

// for printing complex data types
#[derive(Debug)] 
enum List {
    Cons(i32, Box),
    Nil,
}
  
use crate::List::{Cons, Nil};
  
fn main() {
    let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
    println!("{:?}",list)
}

输出:

Cons(1, Cons(2, Cons(3, Nil)))