In Rust is er geen klassieke garbage collector, daarom worden slimme pointers gebruikt voor het beheren van eigendom van complexe structuren. De meest gebruikte zijn:
Box<T> — allocates geheugen voor een object op de heap en overdraagt het eigendom ervan. Wordt gebruikt voor gevallen waarin de grootte van de gegevens niet bekend is tijdens de compilatie of wanneer een verplaatsbare, maar unieke resource vereist is.
Rc<T> (Reference Counted) — referentietelling, stelt meerdere variabelen in staat om het eigendom van onveranderlijke gegevens te "delen" (alleen in een één-thread context).
Arc<T> (Atomic Reference Counted) — implementeert ook referentietelling, maar atomair; gebruik is toegestaan in multi-thread programma's.
RefCell<T> — biedt "interne mutabele" eigendom op runtime, waardoor inhoud zelfs via een onveranderlijke referentie kan worden gewijzigd, maar alleen in één thread (niet thread-veilig!).
Voorbeeld:
use std::rc::Rc; let a = Rc::new(vec![1,2,3]); let b = Rc::clone(&a); // Nu zijn zowel a als b eigenaren van dezelfde gegevens
Kan Rc<T> worden gebruikt in multi-thread code, als alle threads alleen de gegevens lezen? Leg uit.
Antwoord: Nee, dat kan niet! Ondanks dat Rc<T> alleen onveranderlijke toegang tot de gegevens toestaat, is de Rc<T> container zelf niet thread-veilig, omdat het interne referentietel niet beschermd is tegen race conditions. Hiervoor is Arc<T> bedoeld — de interne teller is thread-veilig.
Voorbeeld:
// De volgende code compileert niet! use std::thread; use std::rc::Rc; let five = Rc::new(5); for _ in 0..10 { let five = Rc::clone(&five); thread::spawn(move || { println!("{}", five); }); }
Verhaal
Verhaal
Verhaal
In de business logic module werd RefCell<T> gebruikt voor het organiseren van mutabele toegang tot gegevens, die ook via Arc<T> tussen threads werden doorgegeven. Maar het proberen om RefCell<T> en Arc<T> te combineren leidde tot races en paniek tijdens runtime. Voor een thread-veilige variant had men Mutex<T> of RwLock<T> in plaats van RefCell<T> moeten gebruiken.