Open Source im professionellen Einsatz
Linux-Magazin 08/2015
© 36clicks, 123RF

© 36clicks, 123RF

Mozillas Programmiersprache Rust

Boxenstopp

Mit Version 1.0 legte Mozillas System-Programmiersprache Rust Mitte Mai nach längerer Entwicklungszeit eine erste Verschnaufpause ein. Ob sie sich im weiteren Rennverlauf gegen C und C++ behaupten kann, hängt außer von Mozillas Engagement auch davon ab, ob die Sprache mit ihren Features punktet.

756

Die statisch getypte Programmiersprache Rust [1] legt viel Wert auf Schnelligkeit und Sicherheit. Rust speichert, wie ihr großes Vorbild C, Variablen fester Größe in einem Stack. Zeigerwerte legt es hingegen im Heap des Hauptspeichers ab. Der Code in Listing 1 demonstriert den kontrollierten Umgang mit alloziertem Speicher unter Rust.

Listing 1

Geänderte Besitzverhältnisse (moved_type.rs)

01 fn print_length(vec:Vec<i32>)  {
02   println!("Der Länge des Vektors beträgt {}", vec.len());
03 }
04
05 fn main() {
06   let mut vec:Vec<i32> = vec![1,2,3];
07   print_length(vec);
08   vec.push(4);
09 }

Speichert der Entwickler Listing 1 in der Datei »moved_type.rs« und kompiliert die Software anschließend über »rustc moved.rs« in der Shell, bricht der Compiler den Vorgang mit der Fehlermeldung »moved_type.rs:8:3: 8:6 error: use of moved value: `vec`« für die Zeile 8 ab.

In Listing 1 verweist der im Hauptteil des Programms erzeugte Zeiger »vec« (Zeile 6) auf den Speicherbereich im Heap, der die Repräsentation des Vektors mit den Komponenten »1« , »2« und »3« speichert. Zeile 7 übergibt den Zeiger an die Funktion »print_length()« und macht diese so zum exklusiven Besitzer. In der Konsequenz darf das Programm den Zeiger ab Zeile 7 nicht mehr verwenden, was zu der Fehlermeldung führt.

Will der Entwickler den Zeiger dennoch weiterverwenden, kann er ihn temporär an »print_length()« verleihen (Borrowing). Dazu übergibt er in Zeile 7 von Listing 1 eine Referenz (»&vec« ) und modifiziert analog die Funktionsdeklaration von »print_length()« in Zeile 1 nach »vec: &Vec<i32>« . Soll »print_length()« zudem in der Lage sein, den Zeigerwert zu ändern, greift er alternativ zum Fragment »vec: &mut Vec<i32>« .

Rust erlaubt es dem Entwickler aber nur, eine veränderbare Referenz zu übergeben. Will er den Ressourcenverleih in jedem Aspekt der Programmierung richtig machen, bietet Rust neben dem Borrowing die Angabe von Lifetimes.

Beim Freigeben von alloziertem Speicher verfolgt Rust einen eigenen Ansatz: Das Rust-Kompilat erledigt die Speicherfreigabe selbsttätig und verzichtet dabei auf einen Garbage Collector wie unter Java. Auch die Funktion »free()« [2], wie sie C und C++ unterstützen, muss die Sprache nicht heranziehen, um den Speicherplatz programmgestützt freizugeben.

Ausdrucksstark

Wertet Rust einen Ausdruck aus, ist dessen Rückgabewert das Ergebnis. Doch auch alle Anweisungen besitzen einen Rückgabewert: ein leeres Tupel. Das Semikolon trennt, wie in vielen anderen Sprachen, Ausdrücke und Funktionen, um sie zu gruppieren.

Die Funktion aus Listing 2 ermittelt das Maximum zweier ganzer Zahlen, die sie in der Parameterliste nach dem Funktionsnamen in Zeile 1 übernimmt. Als Datentyp verlangt sie für die Parameter »a« und »b« je eine 32-Bit-Zahl. Der Rückgabewert rechts neben dem »->« -Operator ist vom selben Typ.

Listing 2

Rückgabewerte

01 fn max(a:i32, b:i32) -> i32 {
02   if a > b { return a };
03   b
04 }

Zeile 2 verwendet das Schlüsselwort »return« (»ret« in Version 0.3) und gibt »a« als Resultat zurück. Andernfalls gibt Zeile 3 den Wert von »b« zurück. Die letzte Zeile des Funktionsrumpfes darf auf »return« verzichten.

Schlösse der Programmierer Zeile 3 irrtümlicherweise mit einem Semikolon ab, wäre die Funktion ungültig, denn das würde den Ausdruck »b« in eine Anweisung verwandeln. Damit wäre der Typ des Rückgabewerts ein Tupel und nicht, wie gefordert, eine ganze Zahl.

Musterhaft

Rust bedient sich ausgiebig im Repertoire anderer Sprachen. So verwendet sie, wie die funktionalen Programmiersprachen Haskell [3] und Standard ML [4], Muster – und dies in zahlreichen Kontexten. Mit Hilfe des Musters »(x,y,z)« auf der linken Seite der Zuweisung »let (x,y,z) = (1,2,3);« deklariert die Anweisung die drei Variablen »x« , »y« und »z« auf einen Schlag. Diese auch als Destructuring Assignment bekannte Anweisung weist »x« den Wert »1« , »y« die »2« und »z« die »3« zu.

Der Match-Ausdruck aus Listing 3 verwendet in den Zeilen 2 und 3 jeweils ein Muster zur Fallunterscheidung links neben dem »=>« -Operator. Ergibt der Ausdruck »x« in Zeile 1 den Wert »0« , speichert die Variable »w« die Summe aus »y« und »z« . In jedem anderen Fall speichert »w« das Produkt aus den Werten der beiden Variablen.

Listing 3

Mustererkennung

01 let w = match x {
02     0 => y+z,
03     _ => y*z
04 }

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Rust

    Von der Öffentlichkeit weitgehend unbeachtet arbeitet die Mozilla Foundation an einer eigenen Programmiersprache. Rust soll das Schreiben von zuverlässigen und schnellen nebenläufigen Anwendungen erleichtern. Zu diesem Zweck machen die Entwickler großzügig Anleihen bei anderen Sprachen.

  • Rust 0.12 erschienen

    Die von Mozilla geförderte Programmiersprache Rust erinnert an C und C++ und soll sichere Client- und Serveranwendungen für das Internet ermöglichen. Nun ist Version 0.12 erschienen.

  • Roadmap für Rust 1.0

    Rust-Entwickler Niko Matsakis wagt einen Ausblick auf die Version 1.0 und zählt auf, was bis dahin noch zu tun ist. Unter anderem will man einen Paketmanager und einen festen Release-Zyklus einführen.

  • Rust 1.15 ist fertig

    Die Programmiersprache Rust ist in der stabilen Version 1.15 erschienen. Unter anderem haben die Entwickler das Build-System in Rust unter Einsatz von Cargo geschrieben.

  • Rust 1.0 ist fertig

    Die von Mozilla geförderte Programmiersprache Rust hat die Hürde zur Version 1.0 übersprungen und soll damit für den stabilen Einsatz bereit sein.

comments powered by Disqus

Ausgabe 09/2017

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.