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
包含指向資料1
的Box
的值。如果存取Box
的值,則程式列印‘1’。 當程式結束時,Box
被解除分配。Box
儲存在堆疊中,它指向的資料儲存在堆上。
下面來看看上面例子的圖解表示:
Cons列表
Cons
代表「構造功能」。Cons
列表是一個資料結構,用於從兩個引數構造一個新對,這對稱為List
。x
和y
,那麼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)))