Borrowing dan Mutability

Pada modul ini kita akan membahas mutable reference.

Seperti yang sudah dibahas pada modul sebelumnya, untuk membuat suatu variable menjadi mutable digunakan keyword mut.

Demikian juga dengan reference, digunakan keyword mut setelah tanda &.

let mut x = 5;

&mut x

Mari kita lihat dalam bentuk contoh code

// #[allow(dead_code)]
#[derive(Debug)]
struct Bucket {
    liters: u32,
}

fn pour(src: &Bucket, tar: &Bucket, amount: u32){
    src.liters -= amount;
    tar.liters += amount;
}

fn main(){
    let buck1 = Bucket {liters:20};
    let buck2 = Bucket {liters:10};
    pour(&buck1, &buck2, 3);

    println!("Bucket 1: {:?}", buck1);
    println!("Bucket 2: {:?}", buck2);

}

Jika kita compile akan tampil error:

error[E0594]: cannot assign to `src.liters`, which is behind a `&` reference
 --> src\main.rs:8:5
  |
7 | fn pour(src: &Bucket, tar: &Bucket, amount: u32){
  |              ------- help: consider changing this to be a mutable reference: `&mut Bucket`   
8 |     src.liters -= amount;
  |     ^^^^^^^^^^^^^^^^^^^^ `src` is a `&` reference, so the data it refers to cannot be written

Dapat dilihat, compiler memberikan saran untuk mengubah menjadi mutable. Berikut code setelah diperbaiki menjadi mutable.

#[derive(Debug)]
struct Bucket {
    liters: u32,
}

fn pour(src: &mut Bucket, tar: &mut Bucket, amount: u32){
    src.liters -= amount;
    tar.liters += amount;
}

fn main(){
    let mut buck1 = Bucket {liters:20};
    let mut buck2 = Bucket {liters:10};
    pour(&mut buck1, &mut buck2, 3);

    println!("Bucket 1: {:?}", buck1);
    println!("Bucket 2: {:?}", buck2);

}

Borrowing Rules

Kita dapat memiliki immutable reference lebih dari satu atau hanya satu mutable reference.

Secara ilustrasi, misalnya dalam kelas melukis, terdapat object buah sebagai reference untuk digambar.

Selama itu tidak diubah (immutable), siswa dapat menggambar object tanpa masalah. Disini digambarkan immutable reference lebih dari satu, tidak masalah.

Akan menjadi masalah, ketika ditengah kelas, ada yang mengubah object reference. Siswa tidak menyelesaikan lukisaanya, karena object reference sudah berubah.

Oleh karena itu perubahan harus dilakukan sebelum kelas melukis dimulai. Namun jika lebih dari satu yang berusaha merubah object reference, akan menjadi masalah juga.

Ini menggambarkan hanya satu mutable reference

Berikut contoh code error karena berusaha melakukan borrowing secara mutable dan immutable.

fn main(){
    let mut list = vec![1, 2, 3];
    for i in &list{
        println!("i is {}", i);
        list.push(i+1);
    }
}
error[E0502]: cannot borrow `list` as mutable because it is also borrowed as immutable
 --> src\main.rs:6:9
  |
4 |     for i in &list{
  |              -----
  |              |
  |              immutable borrow occurs here
  |              immutable borrow later used here
5 |         println!("i is {}", i);
6 |         list.push(i+1);
  |         ^^^^^^^^^^^^^^ mutable borrow occurs here

For more information about this error, try `rustc --explain E0502`.

Dapat dilihat dari error yang ditampilkan compiler. Pertama kita melakukan immutable borrow pada for loop, kemudian melakukan mutable borrow pada saat melakukan push.

Silakan lihat dokumentasi push di https://doc.rust-lang.org/std/vec/struct.Vec.html#method.push

Sharing is caring:

Leave a Comment