Rust (Programmiersprache)

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche
Rust
Rust programming language black logo.svg
Basisdaten
Paradigmen: Multiparadigmen (generisch, nebenläufig, funktional, imperativ, strukturiert)
Erscheinungsjahr: 2010; erste stabile Version 2015
Entwickler: Früher Graydon Hoare, heute Rust Project Developers
Aktuelle Version: 1.18  (8. Juni 2017[1])
Typisierung: stark, statisch, linear, Typinferenz
Betriebssystem: Linux, macOS, Windows, FreeBSD, Android, iOS[2]
Lizenz: Apache License 2.0 und MIT License[3]
rust-lang.org

Rust ist eine Multiparadigmen-Programmiersprache, entwickelt von Mozilla Research.[4] Sie wurde entwickelt, um eine sichere, nebenläufige und praxisnahe Sprache zu sein.[5] Sicherheit bedeutet hier, dass solche Programmierfehler weitgehend ausgeschlossen werden, die zu Speicherzugriffsfehlern oder Pufferüberläufen und damit häufig zu Sicherheitslücken führen. Im Gegensatz zu anderen Programmiersprachen mit automatischer Speicherverwaltung verwendet Rust hierfür keine Garbage Collection, sondern setzt auf ein besonderes Typsystem.

Rust vereint Ansätze aus verschiedenen Programmierparadigmen, unter anderem aus der funktionalen, der objektorientierten und der nebenläufigen Programmierung, und erlaubt so ein hohes Abstraktionsniveau. Beispielsweise gibt es in Rust algebraische Datentypen, Pattern Matching, Traits (ähnlich den Typklassen in Haskell), Closures, sowie Unterstützung für RAII. Die Sprache wurde so entworfen, dass die Kosten der Abstraktionen zur Laufzeit so gering wie möglich bleiben können (zero-cost abstractions), um eine mit C++ vergleichbare Effizienz zu erreichen.[6]

Die Sprache entstand aus einem persönlichen Projekt des Mozilla-Mitarbeiters Graydon Hoare. Mozilla begann das Sponsoring des Projekts im Jahr 2009.[7] Es wurde 2010 zum ersten Mal angekündigt.[8] Im selben Jahr begann der Wechsel von einem (noch in OCaml geschriebenen) ersten Compiler zu einem neuen Compiler, der selbst in Rust geschrieben ist.[9] Dieser rustc genannte Compiler verwendet LLVM als Back-End und kann sich seit 2011 erfolgreich selbst übersetzen.[10] Eine erste stabile Version von Compiler und Standardbibliothek, Rust 1.0, wurde am 15. Mai 2015 veröffentlicht.[11]

Sprachdesign[Bearbeiten | Quelltext bearbeiten]

Syntaktisch ist die Sprache an C angelehnt. Mehrere aufeinanderfolgende Anweisungen werden durch ein Semikolon getrennt, Blöcke stehen in geschweiften Klammern. In vielen Details weicht die Syntax allerdings davon ab, so werden beispielsweise keine Klammern um die Bedingungen von if- und while-Statements benötigt, stattdessen aber geschweifte Klammern um den dahinterstehenden Block erzwungen, auch wenn dort nur eine Anweisung steht. Das Schlüsselwort for leitet in Rust immer eine Foreach-Schleife ein, die das Iterieren über beliebige (auch benutzerdefinierte) Container und Objekte ermöglicht. Anstelle des switch-Statements gibt es die wesentlich mächtigeren match-Ausdrücke, die nicht nur mit Zahlen und Zeichenketten umgehen können, sondern Pattern Matching auf beliebig verschachtelten Strukturen durchführen können.

Benutzerdefinierte Datentypen können entweder als struct (Struktur wie in C) oder als enum (tagged-Union) definiert werden. Für beide Arten von Datentypen kann man mittels des impl-Schlüsselswortes Methoden definieren. Die sonst für objektorientierte Programmierung übliche Vererbung gibt es in Rust allerdings nicht, Polymorphie wird stattdessen durch Traits und generische Programmierung ermöglicht. Ein Trait definiert eine Menge von Funktionen und Methoden, die dann jeweils zusammen von Datentypen implementiert werden und bei Typparametern als Einschränkung für die erlaubten Typen dienen können. Dies wird auch für Operatoren verwendet, sodass beispielsweise der Operator + mit jedem Datentyp verwendet werden kann, der den Trait Add implementiert.[12] Alle Funktions-, Methoden- und Operatoraufrufe werden dabei statisch gebunden, wodurch dem Compiler einige Optimierungen ermöglicht werden, allerdings kann über sogenannte Trait-Objects auch mittels dynamischer Bindung auf Trait-Methoden zugegriffen werden. Es ist erlaubt, sowohl existierende Traits aus fremdem Code für benutzerdefinierte Typen, als auch neue, benutzerdefinierte Traits für existierende Typen zu implementieren.

Rust kennt neben den sogenannten Raw-Pointern, die Zeigern in C entsprechen und nur in explizit als unsafe markiertem Code dereferenziert werden dürfen, auch noch Referenzen. Diese zeigen immer auf gültigen Speicher und dürfen niemals den Wert null annehmen. Es werden zwei verschiedene Arten von Referenzen unterschieden: gemeinsame Referenzen (shared references), eingeleitet durch &, und veränderbare Referenzen (mutable references), eingeleitet durch &mut. Der Rust-Compiler garantiert statisch, dass keine Referenz das von ihr referenzierte Objekt „überlebt“, dass das referenzierte Objekt nicht verändert wird, während eine Referenz (egal ob gemeinsam oder veränderbar) existiert, und dass eine veränderbare Referenz – wenn eine solche existiert – stets die einzige Referenz auf ein Objekt ist, sodass Veränderungen am Objekt vorgenommen werden können, ohne dabei Referenzen zum selben Objekt an anderen Stellen im Code oder sogar in anderen Threads ungültig zu machen.

Das Erstellen von Referenzen wird auch als Borrowing (Ausleihen) bezeichnet, und bildet zusammen mit dem Konzept der Ownership (Besitz) die Grundlage für die sichere Speicherverwaltung ohne Garbage Collection. Ownership bedeutet hier, dass jedes Objekt im Speicher im Besitz derjenigen Variable ist, der es bei der Erstellung zugewiesen wird. Am Ende der Lebensdauer dieser Variable wird der Speicher automatisch freigegeben. Für die meisten komplexeren Datentypen verwendet Rust die sogenannte Move-Semantik, sodass bei Zuweisung eines Objektes zu einer anderen Variablen das Objekt „verschoben“ wird, und ein Zugriff auf die alte Variable daraufhin nicht mehr möglich ist. Auch beim Übergeben von Objekten als Wertparameter an Funktionen (call by value) werden solche Objekte in die Funktion „hineingeschoben“ und sind von außen nicht mehr zugreifbar, wenn sie nicht wieder von der Funktion zurückgegeben werden. Primitive Datentypen verwenden keine Move-Semantik, sondern die sonst übliche Copy-Semantik (Zuweisungen erstellen eine Kopie), und bei benutzerdefinierten Datentypen kann mittels des Copy-Traits selbst entschieden werden, ob Move- oder Copy-Semantik verwendet werden soll.

"Hello, world"-Funktion[Bearbeiten | Quelltext bearbeiten]

fn main() {
    println!("Hello, world!");
}

Das obige Beispiel gibt den Text Hello, world! am Ausgabemedium aus. println!() ist hierbei keine gewöhnliche Funktion, sondern ein Makro. Die Funktionsdeklaration erfolgt in Rust mit dem Schlüsselwort fn.

Verwendung[Bearbeiten | Quelltext bearbeiten]

Der Rust-Compiler wird standardmäßig mit Cargo, einer Paketverwaltung für Rust-Software, ausgeliefert, die verwendete Bibliotheken automatisch herunterlädt und Abhängigkeiten auflöst. Eine Vielzahl wiederverwendbarer Open-Source-Komponenten stehen im offiziellen Paket-Repository crates.io[13] zur Verfügung.

Rust findet darüber hinaus unter anderem in folgenden Projekten Verwendung:

Einzelnachweise[Bearbeiten | Quelltext bearbeiten]

  1. Announcing Rust 1.18, The Rust Core Team, 8. Juni 2017
  2. Doc building for ios. Abgerufen am 4. Januar 2015.
  3. COPYRIGHT. Rust compiler source repository. Abgerufen am 17. Dezember 2012.
  4. Mozilla Research Projects. Mozilla Research. Abgerufen am 19. Mai 2015.
  5. The Rust Programming Language. Abgerufen am 21. Oktober 2012.
  6. The Rust Project Developers: The Rust Language FAQ: How fast is Rust? Abgerufen am 19. Mai 2015 (englisch): „That said, it is an explicit goal of Rust to be as fast as C++ for most things.“
  7. Project FAQ. 14. September 2010. Abgerufen am 11. Januar 2012.
  8. Future Tense. 29. April 2011. Abgerufen am 6. Februar 2012: „At Mozilla Summit 2010, we launched Rust, a new programming language motivated by safety and concurrency for parallel hardware, the “manycore” future which is upon us.“
  9. Graydon Hoare: Rust Progress. In: Graydon’s work on Mozilla. 2. Oktober 2010, archiviert vom Original am 19. März 2012, abgerufen am 3. April 2016 (englisch).
  10. Graydon Hoare: [rust-dev] stage1/rustc builds. 20. April 2011. Abgerufen am 20. April 2011: „After that last change fixing the logging scope context bug, looks like stage1/rustc builds. Just shy of midnight :)“
  11. Announcing Rust 1.0
  12. Dokumentation des „Add“-Traits
  13. The Rust community’s crate host. Abgerufen am 3. April 2017 (englisch).
  14. Dave Herman: Shipping Rust in Firefox. In: Mozilla Hacks. 12. Juli 2016, abgerufen am 2. April 2017 (englisch).
  15. Quantum. In: Mozilla Wiki. Abgerufen am 3. April 2017 (englisch).
  16. Rainald Menge-Sonnentag: Mozilla veröffentlicht erste Preview der neuen Browser-Engine Servo. In: Heise Newsticker. 4. Juli 2016, abgerufen am 4. Juli 2016.
  17. Rust’s Redox OS could show Linux a few new tricks, infoworld. Abgerufen am 21. März 2016. 
  18. Cade Metz: The Epic Story of Dropbox’s Exodus From the Amazon Cloud Empire. Wired, 14. März 2016, abgerufen am 3. April 2017 (englisch).
  19. Denis Frank: Using HyperLogLog to Detect Malware Faster Than Ever. Abgerufen am 19. März 2016.
  20. Frank Denis: ZeroMQ: Helping us Block Malicious Domains in Real Time. Abgerufen am 19. März 2016.
  21. Andrew Gallant: ripgrep is faster than {grep, ag, git grep, ucg, pt, sift}. In: Andrew Gallant’s Blog. 23. September 2016, abgerufen am 3. April 2017 (englisch).