Johannes Mainusch: Moin Matthias, schön, dass du da bist. Du bist Experte für die Programmiersprache Rust und hast dazu einen eigenen Podcast namens „Rust in Production“ und mit „Hello, Rust!“ hattest du auch einen YouTube Channel.
Matthias Endler: Ja, und ich bin auch Rust Consultant bei corrode.dev.
Gerade ist Rust in aller Munde und Programmiererköpfen und -herzen; was ist Rust?
Die Programmiersprache Rust kam 2015 als Version 1.0 heraus. Zuvor war sie jahrelang ein Hobbyprojekt eines Entwicklers bei Mozilla, das an Bedeutung gewann, weil Mozilla Probleme mit der C++-Codebase in Firefox hatte, wie zum Beispiel häufige Memory Leaks. Um diese zu beheben, suchten sie nach geeigneten Tools und stießen auf Rust, das schließlich zum Einsatz kam.
Seitdem hat sich Rust stark weiterentwickelt. Viele ursprüngliche Features, wie Garbage Collection und Green Threading, wurden entfernt, und heute ist Rust eine systemnahe Sprache – vergleichbar mit einem modernen C++.
Was macht Rust jetzt so attraktiv, dass eine Firma wie Mozilla oder Entwickler wie du sich dafür interessieren?
Rust kam genau zur richtigen Zeit. Rund 70 Prozent aller Bugs im Browser Chrome sind Memory Safety Issues, die es in Rust schlichtweg nicht gibt. Das heißt, diese Bugs würden gar nicht auftreten, wenn der Browser in Rust geschrieben wäre. Das ist nicht nur Theorie, sondern wird vom Compiler zur Kompilierzeit durch Konzepte wie Borrowing und Ownership garantiert.
Daher kann man sagen, dass der Code in Bezug auf Sicherheit mit großer Wahrscheinlichkeit sehr hohe Ansprüche erfüllt, sobald er kompiliert ist. Das ist in C++ nicht möglich, da man dort viele potenziell unsichere Dinge tun kann – vielleicht performant, aber unsicher. Wer schon einmal eine größere Applikation in C++ geschrieben hat, kennt das Problem mit Nullpointern nur zu gut.
Rust ist eine Systemprogrammiersprache mit dem Slogan „fast, reliable, productive: pick three“ (rust-lang.org)
Rust ist also sicherer als andere Programmiersprachen, weil Borrowing und Ownership eingesetzt werden. Ein Stück Programm, das in C++ geschrieben ist, kann sich benutzten Speicherplatz mit anderen Programmteilen teilen, während in Rust das superrestriktiv gehandhabt wird und ein Stück Programm nur auf seine eigenen und nicht auf andere Speichereinheiten zugreifen kann?
Genau. Wer das verstanden hat, hat Rust verstanden, das ist der Kern. Viele Leute scheitern genau daran. Und du hast es gut zusammengefasst. Stell dir vor, wir teilen uns ein Buch, dann können wir nicht gleichzeitig darin lesen und Notizen machen. Wenn du das Buch gerade nutzt und ich versuche, es zu nehmen, um etwas nachzuschlagen oder zu markieren, dann ist das Buch für mich nicht verfügbar. Das heißt, an der Stelle komme ich nicht weiter und muss warten, bis du fertig bist. Was bei Computern oft passiert, ist, dass der Computer trotzdem versucht, dann einfach auf ein Objekt zuzugreifen, was gar nicht mehr existiert.
Und dann gibt es einen Konflikt zur Laufzeit.
Genau, dann kommt es zu einer Nullpointer Exception. Das Problem entsteht, wenn man zwei Besitzer derselben Datenstruktur hat und beide schreibend darauf zugreifen können. Wenn wir beide nur lesend auf etwas zugreifen, dann weiß ich, dass du es nicht verändern wirst, und du weißt, dass ich es nicht verändern werde. Wenn einer von uns schreibend zugreift, dann ist es auch okay, dann hast du einen „Owner“. Wenn wir aber beide schreibend zugreifen, dann ist die Frage, wer hat die Datenhoheit?
Rust verbietet also die einfache Weitergabe von Speicherplatz. Ist das der Grund, warum Rust ohne Garbage Collection auskommt? Also ohne den Mechanismus, der in anderen Programmiersprachen zur Laufzeit für das „Aufräumen“ verwaister Speicherplätze sorgt?
Genau, das Konzept in Rust garantiert zur Kompilezeit, dass der Speicher immer nur einen Besitzer hat. In C++ gibt es etwas Ähnliches, das nennt sich Resource Allocation Is Initialization (RAII). Allerdings wird dieses Konzept dort nicht vom Compiler erzwungen, sondern es ist eher ein Protokoll, das die Entwickler manuell einhalten müssen. Das macht C++ fehleranfälliger, da es keine automatische Absicherung wie in Rust gibt.
Matthias ist passionierter Open-Source-Entwickler. Er betreut unter anderem den Link Checker „lychee“, der in Rust geschrieben ist.
Wie teile ich nun in Rust einen Wert mit einem anderen Programmteil?
In Rust kann man entweder durch „Borrowing“ einen Wert teilen, eine Kopie eines Werts erstellen oder den Wert moven. Das heißt, wenn man eine Funktion aufruft und ihr eine Variable übergibt, wird diese in die Funktion „umgezogen“ und steht danach nicht mehr zur Verfügung. Das kann für viele zunächst unintuitiv sein – man hat doch nur eine Funktion aufgerufen, und plötzlich ist die Variable weg. Wenn die Funktion jedoch etwas wie delete heißen würde, wäre es klar, dass die Variable danach verschwunden ist.
Der Punkt ist, dass beim Aufruf einer Funktion vieles passieren kann, während man den Pointer noch hält. Moven ist eine Möglichkeit, dies zu verhindern. Eine andere ist das Erstellen einer Kopie, was manchmal explizit, manchmal implizit passiert. Bei einfachen Datentypen wie Integer wird oft automatisch eine Kopie erstellt, da das günstig ist. In der Praxis treten selten Probleme auf, die unergonomisch sind. Meistens überdenkt man das Datenmodell und findet eine bessere Lösung in Rust. Es erfordert ein Umdenken. Wenn man einen Wert nur lesbar teilen möchte, kann man ein kaufmännisches Und-Zeichen (&) davor schreiben und der Wert wird „geborrowed“, also geteilt.
Welche weiteren Merkwürdigkeiten hat Rust? ;-)
Ein weiteres wichtiges Konzept in Rust sind Lifetimes. Mit Lifetimes kann man statisch festlegen, wie lange ein Objekt oder eine Datenstruktur existiert, also während der Laufzeit verfügbar ist. Das passt perfekt zu Borrowing und Ownership, da Lifetimes wie Variablen funktionieren, mit denen man arbeitet, um komplexe Abhängigkeiten auszudrücken.
Zum Beispiel: Wenn man eine Datei von einem Netzwerklaufwerk liest, muss die Verbindung zum Laufwerk so lange bestehen, wie der Reader die Datei liest. Mit einer Lifetime kann man sicherstellen, dass die Verbindung mindestens so lange existiert wie der Reader. Das hilft, solche Abhängigkeiten sicher und klar auszudrücken.
Und wie wird dann der Speicher wieder freigegeben?
In Rust muss klar sein, wann Speicher freigegeben werden darf, und das passiert in der Regel, wenn man den Scope verlässt. Aus anderen Sprachen kennt man vielleicht, dass Variablen aufgeräumt werden, wenn ein Block mit geschweiften Klammern endet. Mit Lifetimes kann man jedoch festlegen, dass eine Variable länger lebt, zum Beispiel solange wie ein übergeordnetes Objekt.
Der Compiler sorgt dafür, dass an den richtigen Stellen free aufgerufen wird, ähnlich wie man es in C manuell machen würde. In Rust erledigt das aber der Compiler, ohne dass der Entwickler sich darum kümmern muss, was Fehler vermeidet.
Rust löst also ein ganz fundamentales problematisches Programmierparadigma auf und macht Memory-Management einfach anders.
Ganz genau. Und wenn man das weiterdenkt, dann hat das sehr positive Effekte auf parallele Programmierung, wenn beispielsweise dort auf Datenstrukturen gleichzeitig Zugriff erfolgt. Plötzlich hat man einfach und sicher die Möglichkeit, die Hardware wirklich komplett auszunutzen, weil eben gewisse Probleme gar nicht existieren. Ich erlebe immer wieder, dass Leute sagen: „Ich kann nun das Ganze ohne Angst parallelisieren“. Das ist dann ein natürlicher Effekt aus dieser Speichersicherheit.
Rust schneidet in vielen Benchmark-Tests als sehr energieeffiziente und performante Programmiersprache ab.
Ja. Außerdem legt Rust großen Wert auf Laufzeit-Performance und optimiert stark darauf, auch wenn die Kompilezeiten relativ langsam sind. Dank des LLVM-Compiler-Backends ist Rust heute zur Laufzeit so schnell wie C und C++, während Sprachen wie Go, Python oder PHP deutlich langsamer sind. Das ist zum Beispiel besonders wichtig für Anwendungen auf Embedded Devices mit geringem Energieverbrauch, wie IoT-Geräte.
Rust ermöglicht frühere Bug-Erkennung, basierend auf langjähriger Consulting-Erfahrung. Quelle: corrode Rust Consulting
Firmen interessieren sich jedoch weniger für Performance und mehr für Kosten. Entscheidend sind Entwicklungskosten und was es kostet, Bugs in Produktion zu beheben. Wenn Rust beispielsweise 30 Prozent der Engineering-Kosten einspart, wird es attraktiver – und auf diesem Weg gelangen Unternehmen dank Rust zu energieeffizienteren Lösungen.
Wie viel Entwicklerschmerz muss ich denn erleiden, bevor es anfängt, Spaß zu machen, in Rust zu arbeiten?
Die Lernkurve beträgt drei bis sechs Monate. Das sind Zahlen, die von Google kommen, von Microsoft und aus meinen eigenen Trainings. Die Leute benötigen einfach Zeit, die Konzepte zu verinnerlichen. Rust verlangt, dass viele Entscheidungen bereits zur Entwicklungszeit getroffen werden – etwa, was passiert, wenn eine Datei nicht geöffnet werden kann, der Inhalt nicht lesbar ist oder kein gültiges UTF-8 ist. Diese Fehlerbehandlung muss klar und explizit erfolgen.
Wie sieht es mit dem Ökosystem aus – ist es mittlerweile groß und stabil, mit vielen Entwicklern, oder ist Rust noch stark im Wandel?
Das Rust-Ökosystem ist mittlerweile sehr ausgereift, besonders die Qualität der Bibliotheken ist beeindruckend. Viele sind überrascht, da sie denken, Rust sei noch zu klein oder nicht weit genug entwickelt. Doch es gibt bereits eine große Anzahl an Crates (Libraries), die zusammen rund 83 Milliarden Mal heruntergeladen wurden. Auch für spezialisierte Bereiche wie Dateiformate, Protokolle oder obskure Anwendungen gibt es zahlreiche Pakete. Zudem existieren mehrere Web-Frameworks und User-Interface-Libraries, was das Ökosystem sehr umfassend macht.
Würdest du sagen, dass man nach drei bis sechs Monaten Einarbeitung in Rusts Ökosystem eine gute Developer Experience erwarten kann?
Im Vergleich zu Go, das stark auf Tag eins optimiert und schon nach etwa einer Woche produktiv ist, aber bei größeren Projekten (ab etwa 10.000 Zeilen Code) auf Einschränkungen stößt, zum Beispiel (in der Vergangenheit) fehlende Generics oder weniger ausgefeiltes Error Handling, optimiert Rust hingegen eher auf Tag zwei: Der Einstieg ist oft mühsamer, aber wenn man das Grundgerüst verstanden hat, wird das Arbeiten, inklusive Refactoring, sehr angenehm.
Wächst die Rust-Community trotz des erhöhten initialen Lernaufwands?
Laut Stack Overflow Survey haben im letzten Jahr etwa 12 Prozent der professionellen Entwickler Rust verwendet, was auf ein stark wachsendes Ökosystem hinweist. In Deutschland setzen viele bekannte Unternehmen Rust als Teil ihrer Toolchain ein, oft ohne viel darüber zu sprechen. Es wird nicht als magische Lösung betrachtet, sondern als Werkzeug, das ein konkretes Problem löst. Ich sehe häufig, dass Entwickler mit kleinen Prototypen beginnen, intensivere Funktionen in Rust umschreiben oder Microservices von C oder Python nach Rust portieren.
Du bist in Deutschland einer der Rust-„Evangelisten“. Hast einen Rust-Podcast. Was besprecht ihr da?
Ich würde mich nicht als Evangelist bezeichnen, sondern eher als Pragmatiker. Wenn Rust für einen Anwendungsfall nicht geeignet ist, sage ich das offen. Allerdings habe ich festgestellt, dass viele interessierte Unternehmen nur wenige Informationen darüber finden, wie andere Firmen Rust nutzen. Deshalb habe ich mit einigen Personen aus meinem Netzwerk gesprochen und sie eingeladen, im Podcast aufzutreten, um dem Mythos entgegenzuwirken, dass Rust nirgends eingesetzt wird. Das Ergebnis war, dass 60 Prozent der Zuhörer durch diese Gespräche mehr Sicherheit und Klarheit über den Einsatz von Rust in Produktionsumgebungen gewonnen haben.
Gibt es schon eine Rust-Konferenz oder wo treffen sich die Rust-Entwickler?
Die größte Rust-Konferenz, RustConf, findet jährlich in Nordamerika statt, dieses Jahr in Montreal, Kanada. In Europa gibt es ebenfalls zahlreiche Rust-Konferenzen, darunter EuroRust im Oktober, RustFest, RustLab und Oxidize, die jeweils spezielle Themen abdecken. Zusätzlich gibt es viele User Groups und Meetups, wie das Rust Cologne Meetup in Köln (siehe: rust.cologne) und weitere in vielen großen deutschen Städten.
Am Ende des Interviews hast du einen Wunsch an die gute Fee frei, Matthias. Der geht in 365 Tagen in Erfüllung. Was wünschst du dir?
Ein Wunsch von mir wäre, dass Unternehmen, die Rust in Deutschland einsetzen, offener darüber sprechen. Oft gibt es spannende Projekte, aber die Marketingabteilung schränkt die Kommunikation ein und erlaubt es nicht, diese nach außen zu teilen. Ich wünsche mir, dass deutsche Firmen ähnlich kommunikativ sind wie amerikanische Unternehmen und bereit sind, über neue Lösungen, Ansätze und Herausforderungen zu diskutieren.
Danke Matthias für das Interview.
Matthias Endler
hat einen M.Sc. in Informatik von der Universität Bayreuth. Er ist ein Open-Source-Maintainer und Rust-Berater. Matthias ist der Gründer von corrode, einer Rust-Beratungsfirma. Seine Interessen sind Skalierbarkeit, Performance und verteilte Systeme, aber auch eingebettete Systeme und Konsolenemulationen. Er lebt in Düsseldorf. Rust ist nach den Rostpilzen benannt, die einen komplexen Lebenszyklus haben.