The stack, the heap, and pointers

Stack, heap, dan pointer sangatlah penting di Rust.

Stack dan heap adalah 2 tempat penyimpanan di komputer. Perbedaannya yang menonjol adalah sebagai berikut:

  • Stack sangat cepat, sedangkan heap tidak terlalu cepat. Bukan berarti heap terlalu lambat, hanya saja stack selalu lebih cepat. Sayangnya, kita tidak bisa hanya menggunakan stack setiap saat, karena:
  • Rust perlu untuk mengetahui ukuran sebuah variabel pada saat compile time. Sehingga variabel sederhana seperti i32 akan ditaruh di stack, karena kita tahu berapa ukuran mereka secara tepat. Anda pasti mengetahui bahwa sebuah i32 akan menggunakan 4 bytes, karena 32 bits = 4 byte. Jadinya i32 bisa selalu ditaruh pada stack.
  • Tapi ada beberapa type yang tidak bisa kita ketahui ukurannya pada compile time. Sedangkan stack perlu tahu berapa ukurannya secara tepat. Jadi apa yang kita lakukan? Pertama, kita taruh datanya pada heap, karena heap bisa menyimpan data dengan berbagai macam ukuran. Dan setelahnya, pointer (alamat dimana data diletakkan pada heap) disimpan ke stack. Cara ini sangatlah masuk akal karena kita selalu tahu ukuran dari sebuah pointer. Jadi, pada dasarnya komputer akan menuju ke stack, baca pointernya (mecari alamat dari data yang ada di heap), dan menuju ke heap dimana data tersebut disimpan.

Pointer terdengar rumit, padahal itu sebenarnya adalah konsep yang sederhana. Pointer itu seperti sebuah daftar isi dari sebuah buku. Bayangkan buku seperti di bawah ini:

MY BOOK

DAFTAR ISI

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

Jadi, buku di atas seakan memiliki 5 buah pointer. Anda bisa membaca mereka dan mencari informasi yang mereka tuliskan pada halaman tersebut. Ada dimanakah chapter tentang "My life"? Ia ada di halaman 1 (it points/mengarahkan to page 1). Ada dimanakah chapter tentang "My job?" Ia ada di halaman 23.

Pointer yang biasa Anda lihat pada Rust biasa disebut sebagai reference. Ini adalah bagian terpenting untuk diketahui: sebuah reference akan mengarahkan kita ke memori dari sebuah value/nilai. Reference artinya kita borrow/meminjam value, tapi kita tidak memilikinya. Ini persis sama seperti buku yang kita bayangkan sebelumnya: daftar isi tidak memiliki informasi apapun. Setiap chapterlah yang justru memiliki informasi. Pada Rust, reference menggunakan tanda & di bagian depannya. Sehingga:

  • let my_variable = 8 akan membuat sebuah variabel biasa, sedangkan
  • let my_reference = &my_variable akan membuat reference.

Anda bisa membaca my_reference = &my_variable seperti berikut: "my_reference adalah sebuah reference ke my_variable". Atau: "my_reference mengacu/menunjuk pada my_variable".

Ini berarti bahwa my_reference hanya sekedar melihat data dari my_variable. my_variable tetap menjadi pemilik atas data tersebut.

Anda juga bisa memiliki sebuah reference yang merujuk ke sebuah reference, ataupun ke sejumlah reference.

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

Kesemuanya itu adalah type yang berbeda. Jika dianalogikan, ini mirip seperti "teman dari temannya si X". Dan itu berbeda dengan "temannya si X", juga berbeda dengan "teman dari temannya dari temannya dari temannya si X".