TIL — Evaluasi Argumen Left-to-Right di Rust
Rust Programming Language
Aldimhr • 09-03-2025 • 2 min read
Masih berhubungan dengan Ownership di Rust, masalah ini muncul ketika saya menggunakan length
dari array
dan array
itu sendiri sebagai argument di function.
Contoh
fn quicksort(arr: &mut Vec<i32>, lo: usize, hi: usize) { ... }
fn main() {
let mut v = vec![1,2,3,4,5];
quicksort(&mut v, 0, v.len() - 1);
}
Function quicksort ketika dijalankan akan muncul error
error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
--> src/lib.rs:5:26
|
5 | quicksort(&mut v, 0, v.len() - 1);
| --------- ------ ^ immutable borrow occurs here
| | |
| | mutable borrow occurs here
| mutable borrow later used by call
Masalah
Error ini berkaitan dengan konsep Ownership, dimana Mutable Borrow &mut v
tidak boleh memiliki banyak reference sekaligus.
let mut a = 10;
let b = &mut a;
let c = a; // error
let d = &mut a; // error
let e = &a; // error
Sama seperti function quicksort sebelumnya, Rust akan membaca argumen dari kiri ke kanan
quicksort(&mut v, 0, v.len() - 1)
Variabel v
diambil di argumen pertama dari function quicksort sebagai Mutable Borrow &mut v
selanjutnya v
dipanggil kembali sebagai Immutable Borrow v.len()-1
di argumen ketiga.
Kenapa
v.len()-1
disebut dengan Immutable Borrow padahal tidak tertulis&v.len()-1
? karena cara kerja method call seperti.len()
secara implisit meneruskan referencev
ke method tersebutlen(&v)
, atau disebut dengan “Automatic Referencing”.
Perbaikan
Ada 2 cara untuk mengatasi error argument reference.
Pertama, menggunakan varibel baru untuk menampung length dari array
fn quicksort(arr: &mut Vec<i32>, lo: usize, hi: usize) { ... }
fn main() {
let mut v = vec![1,2,3,4,5];
let length = v.len(); // buat variabel baru
quicksort(&mut v, 0, length - 1); // perbarui argument ke tiga
}
Variabel baru dibuat untuk menampung length dari array, lalu menggunakan variabel tersebut di argumen ke tiga. Error tidak muncul lagi, karena v.len
dipanggil di awal sebelum v
dipanggil sebagai Immutable Borrow, dan v.len
di variabel length
akan selesai saat variabel sudah menyimpan value di memory. Singkatnya, tidak ada yang menggunakan v
lagi ketika &mut v
dipanggil.
Kedua, re-ordering argument
Cara ini dilakukan dengan menggeser &mut v
ke argument paling akhir untuk menghindari penggunaan banyak reference setelah Mutable Borrow didaftarkan.
fn quicksort(lo: usize, hi: usize, arr: &mut Vec<i32>) { ... }
fn main() {
let mut v = vec![1,2,3,4,5];
quicksort(0, v.len() - 1, &mut v);
}
https://doc.rust-lang.org/reference/expressions.html#evaluation-order-of-operands
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
- Rust
- Rust Argument
- Rust Ownership