Smart Pointer in Rust
Smart Pointer sind eine gängige Datenstruktur in Rust, die zusätzliche Funktionalität und Sicherheitsgarantien bieten, um Speicher und Daten zu verwalten.
In Rust sind Smart Pointer ein Datentyp, der die Eigentümerschaft und Lebensdauerverwaltung von dynamisch zugewiesenem Speicher kapselt.
Smart Pointer kapseln typischerweise einen Rohzeiger und bieten zusätzliche Funktionalität wie Referenzzählung, Eigentumsübertragung, Lebensdauerverwaltung usw.
In Rust bietet die Standardbibliothek mehrere gängige Smart-Pointer-Typen wie Box, Rc, Arc und RefCell.
Anwendungsfälle für Smart Pointer:
- Wenn Sie Speicher auf dem Heap zuweisen müssen, verwenden Sie
Box<T>。 - Wenn mehrere Stellen Eigentümerschaft teilen müssen, verwenden Sie
Rc<T>oderArc<T>。 - Wenn Sie innere Mutabilität benötigen, verwenden Sie
RefCell<T>。 - Wenn Sie threadsichere gemeinsame Eigentümerschaft benötigen, verwenden Sie
Arc<T>。 - Wenn Sie exklusiven Zugriff auf Daten benötigen, verwenden Sie
Mutex<T>。 - Wenn Sie Lese-/Schreibzugriff auf Daten benötigen, verwenden Sie
RwLock<T>。 - Wenn Sie Referenzzyklen auflösen müssen, verwenden Sie
Weak<T>。
Box<T>-Smart Pointer
Box<T> ist einer der einfachsten Smart Pointer in Rust. Er ermöglicht das Zuweisen eines Speicherblocks auf dem Heap und das Speichern eines Werts in diesem Speicher.
Aufgrund der Ownership-Regeln von Rust ermöglicht die Verwendung von Box, Daten bekannter Größe auf dem Heap zu erstellen.
Beispiel
println!("b = {}", b);
Rc<T>-Smart Pointer
Rc<T> (Referenzzählungszeiger) ermöglicht mehreren Eigentümern, Daten gemeinsam zu nutzen. Er verwendet Referenzzählung, um die Anzahl der Eigentümer der Daten zu verfolgen, und gibt die Daten frei, wenn die Anzahl der Eigentümer null erreicht.
Rc<T> eignet sich für die gemeinsame Nutzung von Daten in Single-Threaded-Umgebungen.
Beispiel
let data = Rc::new(5);
let data_clone = Rc::clone(&data);
Arc<T>-Smart Pointer
Arc<T> (atomarer Referenzzählungszeiger) ist ähnlich wie Rc<T>, kann aber Daten in Multithread-Umgebungen sicher gemeinsam nutzen, weil es atomare Operationen verwendet, um den Referenzzähler zu aktualisieren.
Beispiel
let data = Arc::new(5);
let data_clone = Arc::clone(&data);
RefCell<T>-Smart-Pointer
RefCell<T> ermöglicht es, Borrow-Regeln zur Laufzeit zu überprüfen. Es verwendet Interior Mutability, um ein sicheres Interior-Mutability-Muster bereitzustellen, sodass Daten geändert werden können, während unveränderliche Referenzen vorhanden sind.
Allerdings kann RefCell<T> nur in Single-Thread-Umgebungen verwendet werden.
Beispiel
let data = RefCell::new(5);
let mut borrowed_data = data.borrow_mut();
*borrowed_data = 10;
Mutex<T>-Smart-Pointer
Mutex<T> ist eine Sperre für gegenseitigen Ausschluss, die garantiert, dass nur ein Thread jederzeit auf die Daten innerhalb des Mutex zugreifen kann.
Beispiel
let m = Mutex::new(5);
let mut data = m.lock().unwrap();
RwLock<T> Smart Pointer
RwLock<T> ist eine Leser-Schreib-Sperre, die mehreren Lesern gleichzeitig den Zugriff auf Daten ermöglicht, aber Schreibzugriffe sind exklusiv.
Beispiel
let lock = RwLock::new(5);
let read_guard = lock.read().unwrap();
Weak<T> Smart Pointer
Weak<T> ist ein nicht-besitzender Smart Pointer von Rc<T>. Er erhöht den Referenzzähler nicht und wird verwendet, um Probleme mit Referenzzyklen zu lösen.
Beispiel
let five = Rc::new(5);
let weak_five = Rc::downgrade(&five);
Lebensdauer-Verwaltung von Smart Pointern
Smart Pointer können dabei helfen, die Lebensdauer von Daten zu verwalten. Wenn Smart Pointer zerstört werden, geben sie automatisch Speicher frei, wodurch Speicherlecks und hängende Zeiger vermieden werden.
Darüber hinaus ermöglichen Smart Pointer die Angabe eines benutzerdefinierten Destruktors zum Zeitpunkt der Erstellung, um eine benutzerdefinierte Ressourcenverwaltung zu erreichen.
Beispiel
Im Folgenden finden Sie ein vollständiges Beispiel für einen einfachen Rust-Smart-Pointer. Dieses Beispiel verwendet den Rc<T>-Smart-Pointer, um eine einfache Referenzzählung zu implementieren, und demonstriert mehrere Eigentümer, die Daten gemeinsam nutzen.
Beispiel
use std::rc::Rc;
// Definiere eine Struktur zum Speichern von Daten
#[derive(Debug)]
struct Data {
value: i32,
}
// Hauptfunktion
fn main() {
// Erstelle einen Rc-Smart-Pointer, um Daten gemeinsam zu nutzen
let data = Rc::new(Data { value: 5 });
// Klone den Rc-Smart-Pointer, um den Referenzzähler der Daten zu erhöhen
let data_clone1 = Rc::clone(&data);
let data_clone2 = Rc::clone(&data);
// Wert und Referenzanzahl der Daten ausgeben
println!("Datenwert: {}", data.value);
println!("Referenzanzahl: {}", Rc::strong_count(&data));
// Den geklonten Rc-Smart-Pointer ausgeben
println!("Datenklon 1: {:?}", data_clone1);
println!("Datenklon 2: {:?}", data_clone2);
}
Im obigen Code definieren wir zunächst einDatastruct zum Speichern eines Ganzzahlwerts. Dann in dermainFunktion haben wir einenRc<Data>Smart Pointer zum Teilen von Daten erstellt. Dann mit derRc::cloneMethode haben wir zwei Smart Pointer geklont, wodurch die Referenzanzahl der Daten erhöht wurde. Schließlich haben wir den Wert der Daten, die Referenzanzahl und die geklonten Smart Pointer ausgegeben.
Wenn Sie das Programm ausführen, können Sie sehen, dass es den Wert und die Referenzanzahl der Daten sowie die geklonten Smart Pointer ausgibt. DaRcSmart Pointer die Referenzzählung verwenden, um die Anzahl der Besitzer der Daten zu verfolgen, sodass bei jedem Klonen die Referenzanzahl der Daten steigt und die Daten automatisch freigegeben werden, wenn die Anzahl der Besitzer null erreicht.
Die Ausgabe sieht wie folgt aus:
Data value: 5
Reference count: 3
Data clone 1: Data { value: 5 }
Data clone 2: Data { value: 5 }Zusammenfassung
Die Smart Pointer von Rust bieten eine sichere und automatische Möglichkeit, Speicher und Eigentümerschaft zu verwalten.
Smart Pointer sind eine sehr wichtige Datenstruktur in Rust. Sie bieten eine sichere, flexible und bequeme Möglichkeit, Speicher zu verwalten, häufige Probleme mit der Speichersicherheit zu vermeiden und die Zuverlässigkeit und Wartbarkeit von Code zu verbessern.
Smart Pointer sind ein wichtiger Teil des Sicherheitsmodells und ermöglichen Entwicklern, Low-Level-Code zu schreiben, ohne sich um Speichersicherheit sorgen zu müssen.
Durch Smart Pointer behält Rust die Kontrolle von C bei und vermeidet dabei die damit verbundenen Risiken.
Andere Erweiterungen