Was ist das Ownership-Modell in Rust?
Ownership, Borrow-Checker
Das Ownership-Modell ist Rusts Regelwerk für Speicher: Jeder Wert hat genau einen Besitzer, mit dessen Gültigkeitsbereich er freigegeben wird, und der Compiler weist Code zurück, der diese Regel verletzt.
Rust hat keinen Garbage Collector und trotzdem keine baumelnden Zeiger, weil dir der Compiler vorher sagt, an welcher Stelle dein Programm Speicher falsch benutzt.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
- Grundregel
- Jeder Wert hat genau einen Besitzer
- Prüft
- Der Borrow-Checker beim Übersetzen
- Ausleihen
- Viele lesend oder genau einer schreibend
- Kostet zur Laufzeit
- Nichts, die Prüfung ist rein statisch
Besitz und Move
Wenn du einen Wert an eine Funktion übergibst oder einer anderen Variablen zuweist, wandert der Besitz mit. Die alte Variable ist danach nicht mehr benutzbar, der Compiler nennt das moved. Bei einem String bedeutet das: Es wird nichts kopiert, nur die Zuständigkeit für den Speicher wechselt, und freigegeben wird genau einmal, am Ende des neuen Gültigkeitsbereichs.
Einfache Typen wie Zahlen verhalten sich anders, sie werden kopiert, weil das nichts kostet. Für eigene Typen steuerst du das über die Traits Copy und Clone, wobei clone immer ausdrücklich im Code steht. Genau deshalb siehst du in Rust, wo eine tiefe Kopie passiert, und musst sie nicht erraten.
Ausleihen und der Borrow-Checker
Damit nicht ständig Besitz hin- und hergereicht wird, gibt es Referenzen. Die Regel dahinter ist kurz: Entweder beliebig viele lesende Ausleihen oder genau eine schreibende, nie beides gleichzeitig. Der Borrow-Checker prüft das beim Übersetzen, nicht zur Laufzeit.
Diese eine Regel erschlägt eine ganze Fehlerklasse. Kein Zugriff auf freigegebenen Speicher, keine doppelte Freigabe, und im nebenläufigen Fall keine Wettlaufsituation, weil zwei Threads nicht gleichzeitig schreibend an denselben Wert kommen. Lebensdauern beschreiben dabei, wie lange eine Referenz gültig bleiben muss, damit sie nie auf etwas zeigt, das es nicht mehr gibt.
Warum das anfangs weh tut
Der übliche Einstiegsschmerz heißt Kampf mit dem Borrow-Checker. Er entsteht fast immer daraus, dass jemand ein Datenmodell aus einer anderen Sprache mitbringt, in dem mehrere Stellen dieselbe Struktur ändern. In Rust wird daraus entweder ein klarer Besitzer mit kurzen Ausleihen oder ein bewusster Zwischenschritt.
Wenn geteilter Besitz wirklich nötig ist, gibt es Werkzeuge dafür: Rc für die gemeinsame Nutzung in einem Thread, Arc über Threads hinweg, und für Änderungen darunter RefCell oder Mutex. Die verschieben die Prüfung teilweise in die Laufzeit, deshalb greift man erst dazu, wenn der einfache Weg nicht reicht.
Umgekehrt fällt viel weg, was in C++ Disziplin verlangt: Es gibt keine Regel, an die sich alle erinnern müssen, weil der Compiler sie durchsetzt. Der Preis ist ein längerer erster Tag, der Gewinn sind Fehler, die gar nicht erst ins Programm kommen.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Ownership-Modell und was oft damit gleichgesetzt wird
Eine Laufzeitumgebung räumt hier unbenutzte Objekte weg, wann sie es für richtig hält. Rust entscheidet die Freigabe anhand der Gültigkeitsbereiche schon beim Übersetzen, dafür gibt es keine Pausen durch den Aufräumvorgang.
Die Idee, Ressourcen an die Lebensdauer eines Objekts zu binden, ist dieselbe. C++ verlässt sich darauf, dass sich alle im Team daran halten, Rust prüft es und lehnt den Code sonst ab.
In einem unsafe-Block darfst du Dinge tun, die der Compiler nicht prüfen kann, etwa rohe Zeiger dereferenzieren. Die Ownership-Regeln gelten dort weiter, nur die Beweislast liegt bei dir.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Der Compiler streitet früh, dafür fehlt der Absturz später
Wer aus C oder C++ kommt, kennt die Fehlerklasse: Ein Zeiger verweist auf Speicher, der längst freigegeben ist, und das Programm fällt irgendwann an einer ganz anderen Stelle um. Rust verlegt diese Diskussion in die Übersetzung. Der fragliche Code läuft nicht erst und bricht dann zusammen, er wird gar nicht erst gebaut.
Die erste Woche fühlt sich trotzdem zäh an. Der Borrow-Checker lehnt Code ab, der in anderen Sprachen selbstverständlich ist, etwa wenn du eine Liste durchläufst und dabei Elemente änderst. Die üblichen Auswege sind Klonen, wo es billig ist, saubere Trennung von lesenden und schreibenden Referenzen oder Typen wie Rc und RefCell, die die Prüfung in die Laufzeit verschieben.
Wichtig für die Einordnung: Ownership kostet zur Laufzeit nichts. Es gibt keinen Sammler, der das Programm zwischendurch anhält, und keine Referenzzähler, außer du forderst sie ausdrücklich an. Genau deshalb taucht Rust dort auf, wo unvorhersehbare Pausen stören, also in Systemnähe, in Netzwerkdiensten und auf eingebetteter Hardware.
Ownership-Modell lernen
Wo der Borrow-Checker im Alltag wirklich zuschlägt und wie du dein Datenmodell darauf zuschneidest, üben die Rust-Trainings für Entwicklerteams an eigenen Beispielen.
Kurse, die Ownership-Modell behandeln
Häufige Fragen
Muss ich Lebensdauern immer selbst annotieren?
Ist clone eine Niederlage?
Gilt Ownership auch für Nebenläufigkeit?
Deine Ansprechpartner
Du willst das Thema nicht nur nachschlagen, sondern anwenden können? Wir beraten dich persönlich und kostenlos.
Yves Hoppe
Weiterbildung & Beratung
Ordnet mit dir ein, welcher Kurs zu deinem Vorwissen passt.
Norbert Jansen
Beratung & Inhouse
Plant Inhouse-Trainings, die an euren eigenen Daten und Abläufen ansetzen.
Ownership-Modell im Kurs statt im Lexikon
Nachschlagen bringt dich bis zum Verstehen. Anwenden lernst du an echten Aufgaben.