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.
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 happensReferensi 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:
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:
- Anda dapat memiliki sejumlah referensi yang tidak dapat diubah (
&T) ke suatu nilai secara bersamaan. - 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:
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 immutableLingkup 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:
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 pointCobalah sendiri
Berikan referensi s1 yang tidak dapat diubah ke fungsi hitung_panjang menggunakan simbol &.
Tunjukkan petunjuk
Ganti `/* TODO \_/`dengan`&s1` untuk meneruskan referensi yang tidak dapat diubah ke string.
Solusi tersedia setelah 3 upaya
Jadikan variabel s bisa berubah (biarkan mut s) dan berikan referensi yang bisa berubah (&mut s) ke fungsi perubahan agar dapat memodifikasi string.
Tunjukkan petunjuk
Gunakan `biarkan mut s` alih-alih`biarkan s`dan panggil`ubah(&mut s);`.
Solusi tersedia setelah 3 upaya
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.
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