Mochidaz
Mochidaz Professional Tidurers

Bahasa Pemrograman Rust: Smart Pointers - Trait Drop

Bahasa Pemrograman Rust: Smart Pointers - Trait Drop

Seperti yang telah kita ketahui, smart pointer adalah sebuah tipe yang mengimplementasikan trait Deref dan Drop. Kita sudah membahas tentang Deref di artikel sebelumnya. Kali ini, kita akan membahas tentang Drop.

Tentang Drop

Trait Drop dapat diimplementasikan pada tipe apapun, dan hampir akan selalu digunakan ketika kita mengimplementasikan sebuah smart pointer. Trait Drop adalah sebuah trait yang membuat kita dapat mengatur atau mengkustomisasi apa yang akan terjadi bila sebuah nilai keluar dari scope-nya (out of scope). Mari kita ambil Box<T> sebagai contoh. Implementasi kustom tentang apa yang akan terjadi ketika sebuah nilai keluar dari scope-nya pada Box<T> adalah, ia akan mendealokasikan nilai yang ia tunjuk pada heap.

Sekarang, mari kita gunakan constraint trait Debug pada smart pointer Kotak<T> kita kemarin dan semua implementasinya agar kita dapat menampilkan value T pada smart pointer Kotak<T> kita.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use std::ops::Deref;

struct Kotak<T: std::fmt::Debug>(T);

impl<T> Kotak<T>
    where T: std::fmt::Debug {
    fn new(x: T) -> Self {
        Self(x)
    }
}

impl<T> Deref for Kotak<T>
    where T: std::fmt::Debug {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

Lalu kita implementasikan Drop pada Kotak<T> kita.

1
2
3
4
5
6
impl<T> Drop for Kotak<T>
    where T: std::fmt::Debug {
    fn drop(&mut self) {
        println!("Dropping Kotak yang memiliki data {:?}!", self.0);
    }
}

Kita hanya akan menggunakan macro println! untuk sekarang, karena sekarang kita hanya akan berfokus pada bagaimana trait Drop bekerja, dan tidak pada implementasi kustom aslinya seperti mendealokasikan nilai di heap. Sekarang, mari kita lihat fungsi main kita.

1
2
3
4
5
6
fn main() {
	let x = Kotak::new(20);
	{
		let y = Kotak::new("Halo");
	}	
}

Bila kita compile lalu kita jalankan kode kita, maka kita akan menerima output seperti ini:

1
2
Dropping Kotak yang memiliki data "Halo"!
Dropping Kotak yang memiliki data 20!

Lihat, begitu variabel Kotak<T> kita menyentuh akhir dari scope, maka apa yang ada di dalam method drop kita akan terpanggil. Diatas, variabel x akan di-drop ketika ia menyentuh akhir dari scope main sehingga fungsi y akan lebih dahulu di-drop. Karena itulah output Dropping Kotak yang memiliki data "Halo"! keluar lebih dahulu. Selalu ingat bahwa trait Drop ini digunakan untuk mengkustomisasi apa yang akan dilakukan ketika data kita di-drop, bukan kita harus mengimplementasikan trait Drop terlebih dahulu baru data kita dapat di-drop. Rust akan secara otomatis men-drop nilai yang sudah mencapai akhir scope.

Early Drop

Ada kalanya kita ingin men-drop nilai kita lebih dahulu sebelum mencapai akhri scope, seperti saat kita menggunakan lock atau Mutex. Rust melarang kita untuk memanggil method drop secara langsung dari value. Kita harus menggunakan fungsi drop dari std::mem::drop. Kita tidak perlu menggunakan use untuk memanggil fungsi tersebut. Seperti Vec, fungsi itu sudah tersedia didalam prelude.

1
2
3
4
5
6
7
fn main() {
	let x = Kotak::new(20);
	drop(x);
	{
		let y = Kotak::new("Halo");
	}	
}

Dan output yang akan dikeluarkan adalah:

1
2
Dropping Kotak yang memiliki data 20!
Dropping Kotak yang memiliki data "Halo"!

Variabel x akan di-drop terlebih dahulu.

Terima kasih telah membaca :).

comments powered by Disqus