In Rust gibt es keinen klassischen Garbage Collector, daher werden Smart Pointers zur Verwaltung des Besitzes komplexer Strukturen verwendet. Die am häufigsten verwendeten sind:
Box<T> — allokiert Speicher für ein Objekt auf dem Heap und überträgt den Besitz davon. Wird verwendet, wenn die Größe der Daten zur Kompilierzeit nicht bekannt ist oder ein beweglicher, aber einzigartiger Resource benötigt wird.
Rc<T> (Reference Counted) — Referenzzählung, ermöglicht es mehreren Variablen, den Besitz unveränderlicher Daten zu „teilen“ (nur im einsträngigen Kontext).
Arc<T> (Atomic Reference Counted) — implementiert ebenfalls Referenzzählung, jedoch atomar; die Verwendung ist in mehrsträngigen Programmen zulässig.
RefCell<T> — bietet „interne veränderliche“ Besitze zur Laufzeit, was es ermöglicht, den Inhalt selbst über eine unveränderliche Referenz zu ändern, jedoch nur in einem Thread (nicht threadsicher!).
Beispiel:
use std::rc::Rc; let a = Rc::new(vec![1,2,3]); let b = Rc::clone(&a); // Jetzt sind sowohl a als auch b - Besitzer der gleichen Daten
Kann man Rc<T> in mehrsträngigem Code verwenden, wenn alle Threads nur Daten lesen? Erklären Sie.
Antwort: Nein, das kann man nicht! Obwohl Rc<T> nur unveränderlichen Zugriff auf die Daten ermöglicht, ist der Container Rc<T> selbst nicht threadsicher, da die interne Anzahl der Referenzen nicht vor Datenrennen geschützt ist. Dafür ist Arc<T> vorgesehen — sein interner Zähler ist threadsicher.
Beispiel:
// Der folgende Code wird nicht kompilieren! 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); }); }
Geschichte
Geschichte
Geschichte
In einem Geschäftslogik-Modul wurde RefCell<T> verwendet, um einen veränderbaren Zugriff auf Daten zu organisieren, die auch über Arc<T> zwischen Threads weitergegeben wurden. Aber der Versuch, RefCell<T> und Arc<T> zu kombinieren, führte zu Datenrennen und Panik zur Laufzeit. Für die threadsichere Variante sollte Mutex<T> oder RwLock<T> anstelle von RefCell<T> verwendet werden.