Das Ownership-System ist das grundlegende Konzept von Rust zur Gewährleistung der Speichersicherheit auf Compile-Zeit. Jede Variable hat einen Besitzer. Zu einem bestimmten Zeitpunkt kann es nur einen Besitzer einer Ressource geben.
Das Ownership wird bei der Zuweisung oder der Übergabe an eine Funktion übertragen (move). Nach der Übergabe kann der vorherige Besitzer den Wert nicht mehr verwenden:
let s = String::from("hello"); let t = s; // s ist nicht mehr verfügbar
Rust unterscheidet auch zwischen Borrowing (Referenzen).
&T — eine schreibgeschützte Referenz (borrow).&mut T — eine veränderbare Referenz (mutable borrow), aber es darf immer nur eine gleichzeitig existieren.Durch diese Regeln gewährleistet Rust, dass es zu keinen Datenrennen kommt, wenn Werte nach der Freigabe des Speichers verwendet werden, und verhindert andere Fehler bei der Ressourcenverwaltung.
Kann es mehrere veränderbare Referenzen (&mut T) gleichzeitig für denselben Wert geben? Warum?
Antwort: Nein, zu jedem Zeitpunkt kann es entweder beliebig viele unveränderliche Referenzen oder nur eine veränderbare geben. Dies verhindert Datenrennen. Beispiel für fehlerhaften Code:
let mut s = String::from("hi"); let r1 = &mut s; let r2 = &mut s; // Kompilierungsfehler!
Geschichte
In einem Multithreading-Projekt versuchte ein Entwickler, Referenzen auf einen veränderlichen Puffer zu speichern, ohne Ownership zu verwenden, was zu Abbrüchen (use-after-free) führte, als der Puffer vor Abschluss der Bearbeitung durch die Referenz freigegeben wurde. Rust erlaubte es nicht, diesen Code zu kompilieren, daher musste die Architektur geändert werden.
Geschichte
Zu Beginn eines großen Rust-Projekts migrierten Programmierer Code von C++. Sie versuchten, veraltete Gewohnheiten im Umgang mit "rohen" Zeigern zu kombinieren, was zu Fehlern bei der Ressourcennutzung und ständigen Panikattacken des Borrow Checkers führte, bis das architektonische Problem des Ownership gelöst wurde.
Geschichte
In einer String-Parsing-Bibliothek konnten Fehler durch doppelte Speicherfreigaben nur dank des strengen Ownership-Systems von Rust vermieden werden. Eine ähnliche Bibliothek in C++ führte zu schwer auffindbaren Bugs und Speicherlecks.