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

Referensi dan Peminjaman

Di Rust, meneruskan kepemilikan ke fungsi bisa jadi membosankan. Untuk mengatasi ini, Rust menggunakan referensi (&).

Membuat referensi ke suatu nilai disebut Peminjaman.

Referensi yang Tidak Dapat Diubah

Referensi dideklarasikan dengan mengawali tipe atau variabel dengan simbol &. Secara default, referensi tidak dapat diubah: referensi mengizinkan pembacaan nilai tetapi tidak dapat mengubahnya.

Rust
fn main() {
    let s1 = String::from("hello");

    // We pass a reference to s1, not ownership
    let len = calculate_length(&s1);

    // s1 is still usable here!
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize { // s is a reference to a String
    s.len()
} // Here, s goes out of scope, but since it doesn't own the value, nothing happens

Referensi yang Dapat Diubah

Jika Anda perlu mengubah nilai pinjaman, Anda harus menggunakan referensi yang dapat diubah dengan &mut. Variabel asli juga harus dinyatakan bisa berubah dengan mut:

Rust
fn main() {
    let mut s = String::from("hello");

    // We pass a mutable reference
    change(&mut s);

    println!("{}", s); // Prints "hello, world"
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

Aturan Peminjaman

Untuk mencegah kerusakan memori dan data race pada waktu kompilasi, Rust menerapkan dua aturan dasar:

  1. Anda dapat memiliki sejumlah referensi yang tidak dapat diubah (&T) ke suatu nilai secara bersamaan.
  2. ATAU Anda dapat memiliki satu referensi yang dapat diubah (&mut T) ke suatu nilai dalam satu waktu.

Anda benar-benar tidak dapat menggabungkan referensi yang tidak dapat diubah dan dapat diubah untuk nilai yang sama dalam cakupan yang sama:

Rust
let mut s = String::from("hello");

let r1 = &s; // Valid
let r2 = &s; // Valid
// let r3 = &mut s; // COMPILATION ERROR! You cannot create &mut s if s is already borrowed as immutable

Lingkup Referensi dan Masa Hidup Non-Leksikal (NLL)

Secara historis, cakupan referensi berlangsung hingga akhir blok tempat referensi tersebut dibuat. Saat ini, kompiler Rust lebih pintar berkat Non-Lexical Lifetimes (NLL): cakupan referensi berakhir pada baris terakhir yang benar-benar digunakan, tidak harus di akhir blok.

Ini membuat kode berikut ini benar-benar valid:

Rust
let mut s = String::from("hello");
let r1 = &s;
let r2 = &s;
println!("{} and {}", r1, r2); // Last use of r1 and r2. The immutable references expire here!

let r3 = &mut s; // Valid! No active immutable references exist at this point

Cobalah sendiri

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

Berikan referensi s1 yang tidak dapat diubah ke fungsi hitung_panjang menggunakan simbol &.

Memuat editor…
Tunjukkan petunjuk

Ganti `/* TODO \_/`dengan`&s1` untuk meneruskan referensi yang tidak dapat diubah ke string.

Solusi tersedia setelah 3 upaya

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

Jadikan variabel s bisa berubah (biarkan mut s) dan berikan referensi yang bisa berubah (&mut s) ke fungsi perubahan agar dapat memodifikasi string.

Memuat editor…
Tunjukkan petunjuk

Gunakan `biarkan mut s` alih-alih`biarkan s`dan panggil`ubah(&mut s);`.

Solusi tersedia setelah 3 upaya

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

Declare a variable s containing String::from("Rust"). Create two distinct immutable references r1 and r2 to s, and finally print both references separated by a space using the println! macro.

Memuat editor…
Tunjukkan petunjuk

Assign `let r1 = &s;` and `let r2 = &s;` to obtain two immutable references, then print them with `println!("{} {}", r1, r2);`.

Solusi tersedia setelah 3 upaya