Rust Box<T>


Box <T>是一個智慧指標,指向在型別為T的堆上分配的資料。Box <T>允許將資料儲存在堆而不是堆疊上。
Box <T>是一個擁有的指標。
除了將資料儲存在堆上之外,Box沒有效能開銷。
Box離開作用域時,會呼叫解構函式來銷毀所有內部物件並釋放記憶體。

使用Box <T>將資料儲存在堆上。
主要是,Box <T>用於在堆上儲存資料。下面通過一個簡單的例子來理解這一點:

fn main()  
{  
  let a = Box :: new(1);  
  print!("value of a is : {}",a);  
}

執行上面範例程式碼,得到以下結果 -

value of a is : 1

在上面的例子中,a包含指向資料1Box的值。如果存取Box的值,則程式列印‘1’。 當程式結束時,Box被解除分配。Box儲存在堆疊中,它指向的資料儲存在堆上。

下面來看看上面例子的圖解表示:

Cons列表

  • Cons代表「構造功能」。
  • Cons列表是一個資料結構,用於從兩個引數構造一個新對,這對稱為List
  • 假設有兩個元素xy,那麼cons函式cons 「x到y」 表示通過首先放置元素x,然後是元素y來構造新容器。
  • Cons列表包含兩個元素,即當前項和最後一項。 由於Nil不包含下一個專案,因此缺點列表的最後一項是Nil

現在,建立包含cons列表的列舉。

enum List  
{  
   cons(i32, List),  
   Nil,  
}

在上面的程式碼中,建立了List型別的列舉,其中包含i32值的cons列表資料結構。

現在,在以下範例中使用上面的List型別:

enum List {  
    Cons(i32, List),  
    Nil,  
}  
use List::{Cons, Nil};  
fn main()  
{  
  let list = List::Cons(1,Cons(2,Cons(3,Nil)));  
  for i in list.iter()  
  {  
    print!("{}",i);  
  }  
}

執行上範例程式碼,得到以下結果 -

在上面的範例中,Rust編譯器丟擲錯誤「具有無限大小」,因為List型別包含遞回的變體。 因此,Rust無法找出儲存List值所需的空間。 使用Box <T>可以克服無限大小的問題。

使用Box <T>獲取遞回型別的大小

Rust無法確定儲存遞回資料型別需要多少空間。 Rust編譯器在前一種情況下顯示錯誤:

= help: insert indirection (e.g., a 'Box', 'Rc', or '&') at some point to make 'List' representable

在上面的例子中,可以使用Box <T>指標,因為編譯器知道Box <T>指標需要多少空間。 Box <T>指標的大小在程式執行期間不會改變。 Box <T>指標指向將儲存在堆上而不是cons變數中的List值。 Box <T>指標可以直接放在cons變數中。

下面來看一個簡單的例子 -

#[derive(Debug)]   
enum List {  
    Cons(i32, Box<List>),  
    Nil,  
}  
use List::{Cons, Nil};  
fn main()  
{  
  let list = Cons(1,Box::new(Cons(2,Box::new(Cons(3,Box::new(Nil))))));  

    print!("{:?}",list);  

}

執行上面範例程式碼,得到以輸出結果如下 -

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