Lompati ke konten utama
Modul 3 · Pelajaran 1 dari 25/14 dalam kursus~15 min
Pelajaran modul (1/2)

Aturan Kepemilikan

Kepemilikan adalah fitur paling unik dari Rust. Hal ini memungkinkan bahasa untuk menjamin keamanan memori tanpa memerlukan Pengumpul Sampah atau memaksa Anda untuk membatalkan alokasi memori heap secara manual (seperti di C atau C++).

Tiga Aturan Kepemilikan

Manajemen memori di Rust diatur oleh tiga aturan sederhana yang diperiksa secara ketat oleh compiler:

  1. Setiap nilai di Rust memiliki variabel yang disebut pemiliknya.
  2. Hanya boleh ada satu pemilik dalam satu waktu.
  3. Saat pemilik keluar dari cakupan, nilainya otomatis hilang.

Tumpukan vs Tumpukan

Untuk memahami kepemilikan, penting untuk mengetahui di mana data berada:

  • Stack: menyimpan data berukuran tetap yang diketahui pada waktu kompilasi (misalnya bilangan bulat, boolean). Akses sangat cepat.
  • Heap: menyimpan data berukuran dinamis yang tidak diketahui pada waktu kompilasi (misalnya, String). Alokasi lebih lambat dan memerlukan pointer yang disimpan di Stack.

Konsep "Bergerak"

Saat kita menetapkan variabel yang dialokasikan heap ke variabel lain, Rust memindahkan (atau mentransfer) kepemilikan nilai tersebut, sehingga membuat variabel pertama menjadi tidak valid:

Rust
let s1 = String::from("ciao");
let s2 = s1; // Ownership of the text moves to s2. s1 is NO longer usable!

// println!("{}", s1); // COMPILATION ERROR! s1 is "borrow of moved value"
println!("{}", s2); // Valid!

Perilaku ini menghindari "kesalahan bebas ganda" (mencoba mengosongkan memori yang sama dua kali saat keluar dari cakupan), karena hanya s2 yang akan mengosongkan memori.

Konsep "Klon" (Salinan Dalam)

Jika kita secara eksplisit perlu menyalin seluruh konten String (baik penunjuk tumpukan maupun data teks aktual di heap), kita dapat menggunakan metode .clone(). Ini sepenuhnya menduplikasi data di heap, menjaga variabel asli dan variabel baru tetap valid, dengan mengorbankan overhead kinerja untuk alokasi memori baru:

Rust
let s1 = String::from("ciao");
let s2 = s1.clone(); // Deep copy. Both variables remain valid!
println!("s1: {}, s2: {}", s1, s2);

Konsep "Salinan"

Untuk tipe sederhana yang disimpan seluruhnya di Stack (seperti bilangan bulat i32, boolean bool, karakter char), penetapan akan melakukan penyalinan dangkal otomatis yang sebenarnya, yang berarti kedua variabel tetap valid:

Rust
let x = 5;
let y = x; // Copies the value 5 onto the stack. Both variables are usable!
println!("x: {}, y: {}", x, y); // Valid!

Cobalah sendiri

Latihan#rust.m3.l1.e1
Upaya: 0Memuat…

Deklarasikan String s1 yang berisi teks 'halo'. Tetapkan s1 ke s2 (untuk memindahkan kepemilikan). Terakhir, cetak s2 menggunakan println!.

Memuat editor…
Tunjukkan petunjuk

Gunakan `let s2 = s1;` untuk mentransfer kepemilikan ke `s2` dan mencetaknya dengan `println!('{}', s2);`.

Solusi tersedia setelah 3 upaya

Latihan#rust.m3.l1.e2
Upaya: 0Memuat…

Deklarasikan variabel integer x dengan nilai 5. Tetapkan x ke y (melakukan penyalinan). Terakhir, cetak x dan y dalam println yang sama! penyataan.

Memuat editor…
Tunjukkan petunjuk

Lakukan `let y = x;` lalu cetak kedua nilai, misalnya, `println!('{} {}', x, y);`.

Solusi tersedia setelah 3 upaya

Latihan#rust.m3.l1.e3
Upaya: 0Memuat…

Declare a String s1 with the value "Rust". Create a deep copy of s1 in a new variable s2 using the clone method. Finally, print both s1 and s2 separated by a space using the println! macro.

Memuat editor…
Tunjukkan petunjuk

Use `let s2 = s1.clone();` to deep copy the value of `s1` into `s2`, then print them with `println!("{} {}", s1, s2);`.

Solusi tersedia setelah 3 upaya