Rust 中的Box指標使遞迴型別成為可能 - Knoldus Blogs

banq發表於2021-12-02

指標是包含在儲存器中的地址的變數的一般概念的程式設計。Rust智慧指標是一種資料結構,不僅可以充當指標,還具有額外的後設資料和功能。Box指標是 Rust 中的智慧指標之一。
Box指標讓您將資料儲存在堆上而不是棧上,儲存在棧上的就是指向堆中資料的指標。

let ptr = Box::new(25);


我們在以下情況下使用 Box –
  • 當您的型別在編譯時無法知道其大小,並且您想在需要精確大小的上下文中使用該型別的值時
  • 如果您有大量資料並且想要轉移所有權,但要確保這樣做時不會複製資料
  • 當你想擁有一個值並且你只關心它是一個實現特定特徵的型別而不是特定型別時

 

使用 Box Type型別 儲存資料
正如我們上面討論的,box Type型別用於在堆上而不是棧上儲存資料。指向堆上資料的指標確實儲存在棧中。這裡有一個例子可以更好地解釋它。

fn main() {
    let ptr = Box::new("hello");
    println!("The pointer points to data : {}", ptr);
}

在上面的示例中,有一個變數ptr儲存指向字串“hello”的Box 指標。字串 hello 在堆上,box指標ptr在棧上。該程式將列印以下內容 :

The pointer points to data : hello

PTR變數擁有Box指標,因此規則的所有權適用於它。隨著main方法的結束,ptr box指標指向的記憶體會被釋放,棧上的box指標也會被釋放。
 

使用Box指標的遞迴型別
在任何程式語言中,編譯器都需要知道任何資料型別佔用的空間。這對於 Rust Compiler 來說是一樣的,但是在遞迴 型別的情況下,這是相當困難的,遞迴型別其中值可以具有作為自身的一部分的另一值相同型別,編譯器不知道在編譯時為這種資料型別分配多少記憶體。這裡有一個例子可以更好地解釋它。

enum RecType {
    Cons(i32, Rectype),
    Nil,
}

這裡,RecType是一個遞迴列舉,它有一個與元組 (i32, RecType)相關聯的變體。該元組包含一個i32值和一個相同型別的值,即RecType。因此,在這種情況下,編譯器在編譯時很難為RecType分配空間。
為了克服這個問題,我們可以使用Box 指標。由於我們可以知道Box 指標在編譯時佔用的空間,因此我們可以在元組中使用Box 指標來指向RecType型別的值。這是一個示例,可以更好地向您展示。

enum RecType {
    Cons(i32, Box<RecType>),
    Nil,
}


現在,這將編譯沒有任何問題。
現在編譯器知道要為RecType分配多少空間,因為我們知道RecType列舉中每個變體的大小。以下是我們如何使用此RecType遞迴儲存資料。

use crate::RecType::{Cons, Nil};

fn main() {
    let data = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}





 

相關文章