堆疊、堆積和指標

堆疊(stack)、堆積(heap)和指標(pointer)在 Rust 中非常重要。

堆疊和堆積是電腦中保存記憶體的兩個地方。主要的區別在:

  • 堆疊的速度非常快,但堆積就不那麼快了。它也不是超慢,但堆疊總是更快。但是你不能一直使用堆疊,因為:
  • Rust 在編譯時必需知道變數的大小。所以像 i32 的簡單變數就放在堆疊上,因為我們知道它們的確切大小。你總是知道 i32 要 4 位元組,因為 32 位元 = 4 位元組。所以 i32 總是可以放在堆疊上。
  • 但有些型別在編譯時不知道大小。但是堆疊需要知道確切的大小。那麼你該怎麼做呢?首先你把資料放在堆積中,因為堆積中可以有任何大小的資料。然後為了找到它,一個指標就會放上堆疊。這樣沒問題,因為我們總是知道指標的大小。所以,電腦就會先去堆疊讀取指標,然後跟著指標到資料所在的堆積。

指標聽起來很複雜,但它們很容易。指標就像一本書的目錄。想象一下這本書:

MY BOOK

TABLE OF CONTENTS

Chapter                        Page
Chapter 1: My life              1
Chapter 2: My cat               15
Chapter 3: My job               23
Chapter 4: My family            30
Chapter 5: Future plans         43

所以這就像有五個指標。你可以閱讀它們,找到它們所說的資訊。"My life" 這一章在哪裡?它在第 1 頁(它 指向 第 1 頁)。"My job" 這一章在哪裡?它在第23頁。

通常在 Rust 中看到的指標稱做 參考。重點在於知道:一個參考指向另一個值的記憶體位置。參考意味著你 了這個值,但你並不擁有它。這和我們的書一樣:目錄並不擁有資訊。章節裡才有資訊。在 Rust 中,參考的前面有一個 &。所以:

  • let my_variable = 8 是一個正規的變數,但是:
  • let my_reference = &my_variable 是一個變數參考。

你把 my_reference = &my_variable 讀成這樣:"my_reference 是對my_variable 的參考" 或者:"my_reference 參照到 my_variable"。

這意味著 my_reference 只看 my_variable 的資料。my_variable 仍然擁有它的資料。

你也可以有一個參考的參考,或者任何數量的參考。

fn main() {
    let my_number = 15; // 這是 i32
    let single_reference = &my_number; //  這是 &i32
    let double_reference = &single_reference; // 這是 &&i32
    let five_references = &&&&&my_number; // 這是 &&&&&i32
}

這些都是不同的型別,就像 "朋友的朋友"和 "朋友"不同一樣。