Smart Pointers — Rust

Smart Pointers di Rust Smart pointer adalah struct yang bertindak seperti pointer tapi punya metadata & kemampuan tambahan. Mereka memungkinkan pola ownership y

Smart Pointers di Rust

Smart pointer adalah struct yang bertindak seperti pointer tapi punya metadata & kemampuan tambahan. Mereka memungkinkan pola ownership yang tidak bisa diekspresikan dengan reference biasa.

Box<T> — Heap Allocation

Box<T> menyimpan data di heap, dengan pointer di stack. Berguna untuk:

let b = Box::new(5);
println!("{}", b);  // 5

// Recursive type — tanpa Box, Rust tidak tahu ukuran List
enum List {
    Cons(i32, Box<List>),
    Nil,
}

use List::{Cons, Nil};
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));

Rc<T> — Reference Counting (Single-Threaded)

Rc<T> (Reference Counted) memungkinkan banyak owner untuk data yang sama — menghitung jumlah reference dan men-drop data saat count 0.

use std::rc::Rc;

let a = Rc::new(String::from("halo"));
let b = Rc::clone(&a);  // +1 ref count (bukan deep clone!)
let c = Rc::clone(&a);

println!("count: {}", Rc::strong_count(&a));  // 3

Catatan: Rc<T> tidak thread-safe. Data yang di-share hanya bisa dibaca (immutable).

Arc<T> — Atomic Reference Count (Multi-Threaded)

use std::sync::Arc;
use std::thread;

let data = Arc::new(vec![1, 2, 3]);
let mut handles = vec![];

for i in 0..3 {
    let data = Arc::clone(&data);
    handles.push(thread::spawn(move || {
        println!("Thread {}: {:?}", i, data);
    }));
}
for h in handles { h.join().unwrap(); }

Arc sama seperti Rc tapi pakai atomic operations — aman untuk thread.

RefCell<T> — Interior Mutability

RefCell<T> memindahkan aturan borrow checker dari compile time ke runtime. Kamu bisa mendapatkan &mut bahkan saat RefCell itu sendiri immutable.

use std::cell::RefCell;

let c = RefCell::new(5);

*c.borrow_mut() += 10;
println!("{}", c.borrow());  // 15

Hati-hati: kalau aturan borrow dilanggar saat runtime, program panic!

Rc<RefCell<T>> — Shared Mutable State

use std::rc::Rc;
use std::cell::RefCell;

let data = Rc::new(RefCell::new(vec![1, 2, 3]));

let ref1 = Rc::clone(&data);
let ref2 = Rc::clone(&data);

ref1.borrow_mut().push(4);
ref2.borrow_mut().push(5);

println!("{:?}", data.borrow());  // [1, 2, 3, 4, 5]

Decision Matrix

KebutuhanPakai
Data heap, single ownerBox<T>
Banyak owner, single-thread, immutableRc<T>
Banyak owner, multi-thread, immutableArc<T>
Interior mutability, single-threadRefCell<T>
Shared mutable, single-threadRc<RefCell<T>>
Shared mutable, multi-threadArc<Mutex<T>>

Yang akan kamu pelajari