Abo
  • Services:
Anzeige
Rust ist nach den Pflanzenparasiten der Rostpilze benannt.
Rust ist nach den Pflanzenparasiten der Rostpilze benannt. (Bild: Martin Wolf/Golem.de)

Syntax und Programmierstil

Da sich Programmierer meistens an die Syntax und Semantik ihrer Lieblingssprache gewöhnen, hier ein paar Worte aus der Sicht eines C/C++-Programmierers. Auf den ersten Blick ähnelt die Syntax im Hello-World-Programm stark der Programmiersprache C. Wird allerdings ein größeres Projekt betrachtet, sind fast keine Ähnlichkeiten zu C mehr zu erkennen, sondern mehr zu Python und C++.

Eine Funktion, die vor allem Benutzern von Skriptsprachen bekannt vorkommen wird, ist die Unterstützung von Tupeln direkt in der Programmiersprache. Dies ermöglicht es, aus einer Funktion heraus mehrere Werte zurückzugeben.

Anzeige

Ebenfalls ähnlich wie bei vielen Skriptsprachen verhält sich der Operator "let", der Variablen deklariert und initialisiert. Er kann im Gegensatz zu C/C++ links und rechts des "="-Operators mehrere Elemente verarbeiten und benutzt Pattern Matching, um die jeweiligen Elemente zuzuweisen.

Anders als bei vielen verbreiteten Programmiersprachen müssen in Rust Variablen mit dem Schlüsselwort "mut" explizit als veränderbar markiert werden, während ansonsten meist Konstanten explizit als solche definiert werden müssen. Wird eine Variable ohne "mut" initialisiert und darauf geschrieben, lässt sich das Programm nicht kompilieren.

  1. // Funktion, die ein Tupel zurückgibt
  2. fn get_tuple() -> (i8,i8)
  3. {
  4. let a = 4;
  5. let b = 2;
  6. // a und b zu Tupel zusammenfassen
  7. (a,b)
  8. }
  9.  
  10. fn main()
  11. {
  12. // pattern matching, um das Tupel wieder zu trennen
  13. let (x1, x2) = get_tuple();
  14.  
  15. println!("x1: {}", x1);
  16. println!("x2: {}", x2);
  17.  
  18. // Werte sind automatisch Konstanten
  19. let ro = 3;
  20. // Variable als veränderbar deklarieren
  21. let mut rw = 2;
  22.  
  23. rw = 10; // zulässig
  24. // ro = 7; unzulässig,
  25. }

Sichere und effiziente Speicherverwaltung

Bei Rust muss sich der Programmierer wenig mit der Speicherverwaltung auseinandersetzen, alle primitiven Datentypen werden am Stack abgelegt, die restlichen auf dem Heap. Allerdings steht, um Daten explizit am Heap abzulegen, der Zeigertyp "Box" zur Verfügung.

Darüber hinaus ist Rust mit dem Ziel erstellt worden, eine sichere Sprache für parallel ablaufende Programme zu sein und dabei dennoch die Geschwindigkeit von C/C++ zu erreichen. Dazu werden viele unsichere Speicherzugriffe bereits zur Kompilierzeit erkannt, was der Sprache eine aufwendige Laufzeitumgebung erspart und sie so effizienter macht als andere High-Level-Programmiersprachen wie C# und Java. Rust verhindert außerdem sogenannte Data Races. Diese treten auf, wenn mehrere Threads dieselben Datenbereiche bearbeiten oder mehrere Zeiger auf einem Speicherbereich existieren, was zu unerwünschtem Verhalten des Programms führen kann.

Rust setzt für die sicheren Speicherzugriffe auf ein System von Zeigerbesitzrechten (Pointer Ownership) und Zeigerlebenszeiten (Pointer Lifetime). Durch Pointer Ownership wird garantiert, dass immer nur eine Referenz auf ein Objekt existiert. Durch Pointer Lifetime wird sichergestellt, dass, sobald die Referenz auf ein Objekt den Arbeitsbereich verlässt, dessen Speicher freigegeben wird.

Außerdem kann eine Funktion einen Zeiger ausborgen (Borrowing), dabei erhält die Funktion vorübergehend eine Referenz auf die Daten, die nach dem Verlassen der Funktion dann nicht freigegeben wird und somit weiter verwendet werden darf. Rust kann mit diesem System allerdings nur eine bestimmte Klasse von Fehlern in der Speicherverwaltung verhindern.

Dazu zählen Nullzeigerdereferenzierung, Zugriff auf bereits freigegebenen Speicher (Use after free), Lesen von nicht initialisiertem Speicher (liefert undefinierte Daten) sowie mehrfaches Freigegeben von Speicher (double free). Explizit nicht zu dieser Gruppe gehören Integer Overflows und das Lesen zum Beispiel über eine Array-Grenze hinaus (Out of Bounds Access). Letzteres ist im Gegensatz zu C/C++ aber definiertes Verhalten und führt zu einem "panic", einem sicheren Beenden des Programms.

Hier ein kurzes Beispiel zu Zeigern in Rust:

// verwendet eine Referenz auf die Variable
fn borrow_var(a: &Vec<i8>)
{
	// Hier wird a verwendet
	println!("a[0] in borrow: {}", a[0]);
	// a wird nicht freigegeben
}

// übernimmt die ganze Variable
fn move_var(b: Vec<i8>)
{
   println!("b[0] in move: {}", b[0]);
   // b wird freigegeben und ist somit in main() nicht mehr vorhanden
}

fn main()
{
	let v1 = vec![1, 2, 3];	// Vektor mit 1,2,3 als Inhalt
	borrow_var(&v1);	// Funktionsaufruf mit Borrowing-Verhalten
	move_var(v1);		// Funktionsaufruf mit Move-Verhalten

	// Funktioniert nicht, da v1 schon an move_var() übergeben wurde
	//println!("v1[0] in main: {}", v1[0]);
}

Im obigen Beispiel sind Pointer Ownership, Lifetime und Borrowing praktisch dargestellt. Zuerst wird ein Vektor auf dem Heap abgelegt und eine Referenz darauf in "v1" gespeichert, "v1" "gehört" nun der Funktion "main()". Der Funktion "borrow_var()" wird nun mit dem "&"-Operator eine Referenz geborgt, sie wird in der Funktion verwendet und kann anschließend wieder in "main()" benutzt werden.

Im zweiten Schritt wird nun "v1" ohne den "&"-Operator übergeben, dies bedeutet, "v1" gehört nun "move_var()". Endet der Arbeitsbereich der Funktion, endet auch die Lebenszeit von "v1" und der Speicher wird freigegeben. Rust verhindert auch, dass "v1" innerhalb von "main()" weiterverwendet wird. Da der Speicher ja bereits freigegeben wurde, führt ein Zugriff darauf zu einem Fehler beim Kompilieren.

In C wäre es ohne Fehler beim Kompilieren möglich, den Speicher einer Variablen freizugeben und anschließend darauf zuzugreifen. Prompt hätte man einen Absturz des Programms oder eine schwere Sicherheitslücke, da das Betriebssystem den Speicher vielleicht schon anderweitig verwendet hat.

Such dir deine Garantien aus!

In dem Beispiel wurden nur einfache Referenzen benutzt, die vom Rust-Compiler statisch geprüft werden können. In der Standardbibliothek finden sich allerdings auch viele Implementierungen intelligenter Referenzen, die jeweils bestimmte Eigenschaften garantieren und andere undefiniert lassen, um schneller zu sein.

So zum Beispiel "Rc", der einem Zeiger mit Referenzzählung entspricht. Dieser garantiert zur Laufzeit, dass der Speicher erst dann freigegeben wird, wenn die letzte Referenz darauf freigegeben wurde, aber nicht, dass keine zyklischen Referenzen entstehen, was zu Speicherlecks führt.

Dieses Verhalten funktioniert jedoch nur innerhalb eines Threads, für Anwendungen mit mehreren Threads oder andere Sonderfälle existieren wiederum verschiedene andere Referenztypen, die hier detailliert aufgelistet sind.

Dieses System ähnelt sehr stark den intelligenten Zeigern in C++, die eine feinkörnige Auswahl aus nötigen Garantien ermöglichen und somit die Ausführungsgeschwindigkeit hochhalten. Java und C# gehen hier den Weg über einen Garbage Collector, der zur Laufzeit immer wieder nicht mehr referenzierte Objekte aus dem Speicher entfernt; natürlich geht das Aufräumen dann auch auf Kosten der Verarbeitungsgeschwindigkeit.

 Rust: Ist die neue Programmiersprache besser?Die dunkle Seite von Rust 

eye home zur Startseite
olleIcke 05. Jul 2016

Versteh ich auch nicht. Ich sehe durchaus, dass das Interesse riesig is! Nörgler mit so...

Bachsau 23. Jun 2016

Ein weiteres mal, dass deutlich darauf hingewiesen werden muss, dass JavaScript und Java...

zZz 23. Jun 2016

Ich erinnere mich an einen Artikel (Wired?), in dem die Dropbox-Macher ihre Entscheidung...

Baron Münchhausen. 21. Jun 2016

Genau! Ich will, dass mein Programm einfach das Wasser auf den Herd stellt, wenn ich es...

Pete Sabacker 19. Jun 2016

http://www.edm2.com/0405/enumeration.html



Anzeige

Stellenmarkt
  1. Robert Bosch Starter Motors Generators GmbH, Schwieberdingen
  2. DATAGROUP Köln GmbH, Berlin, Dessau
  3. Universitätsmedizin der Johannes Gutenberg-Universität Mainz, Mainz
  4. Holz-Henkel GmbH & Co. KG, Göttingen


Anzeige
Top-Angebote
  1. (u. a. London Has Fallen, The Imitation Game, Lone Survivor, Olympus Has Fallen)
  2. (u. a. Der Hobbit 3, Der Polarexpress, Ice Age, Pan, Life of Pi)
  3. (u. a. 96 Hours Taken 3 6,97€, London Has Fallen 9,97€, Homefront 7,49€, Riddick 7,49€)

Folgen Sie uns
       


  1. Red Star OS

    Sicherheitslücke in Nordkoreas Staats-Linux

  2. Elektroauto

    Porsche will 20.000 Elektrosportwagen pro Jahr verkaufen

  3. TV-Kabelnetz

    Tele Columbus will Marken abschaffen

  4. Barrierefreiheit

    Microsofts KI hilft Blinden in Office

  5. AdvanceTV

    Tele Columbus führt neue Set-Top-Box für 4K vor

  6. Oculus Touch im Test

    Tolle Tracking-Controller für begrenzte Roomscale-Erfahrung

  7. 3D Xpoint

    Intels Optane-SSDs erscheinen nicht mehr 2016

  8. Webprogrammierung

    PHP 7.1 erweitert Nullen und das Nichts

  9. VSS Unity

    Virgin Galactic testet neues Raketenflugzeug

  10. Google, Apple und Mailaccounts

    Zwei-Faktor-Authentifizierung richtig nutzen



Haben wir etwas übersehen?

E-Mail an news@golem.de


Anzeige
Robot Operating System: Was Bratwurst-Bot und autonome Autos gemeinsam haben
Robot Operating System
Was Bratwurst-Bot und autonome Autos gemeinsam haben
  1. Roboterarm Dobot M1 - der Industrieroboter für daheim
  2. Roboter Laundroid faltet die Wäsche
  3. Fahrbare Roboter Japanische Firmen arbeiten an Transformers

Super Mario Bros. (1985): Fahrt ab auf den Bruder!
Super Mario Bros. (1985)
Fahrt ab auf den Bruder!
  1. Quake (1996) Urknall für Mouselook, Mods und moderne 3D-Grafik
  2. NES Classic Mini im Vergleichstest Technischer K.o.-Sieg für die Original-Hardware

HPE: Was The Machine ist und was nicht
HPE
Was The Machine ist und was nicht
  1. IaaS und PaaS Suse bekommt Cloudtechnik von HPE und wird Lieblings-Linux
  2. Memory-Driven Computing HPE zeigt Prototyp von The Machine
  3. Micro Focus HP Enterprise verkauft Software für 2,5 Milliarden Dollar

  1. Re: Sieht gut aus

    ChristianKG | 02:37

  2. Re: SMS unsicher?

    Proctrap | 02:28

  3. Re: Betrifft nur wenige

    HorkheimerAnders | 01:50

  4. Re: Audio?

    Pjörn | 01:48

  5. Re: Nächste Stufe ...

    NukeOperator | 01:35


  1. 17:25

  2. 17:06

  3. 16:53

  4. 16:15

  5. 16:02

  6. 16:00

  7. 15:00

  8. 14:14


  1. Themen
  2. A
  3. B
  4. C
  5. D
  6. E
  7. F
  8. G
  9. H
  10. I
  11. J
  12. K
  13. L
  14. M
  15. N
  16. O
  17. P
  18. Q
  19. R
  20. S
  21. T
  22. U
  23. V
  24. W
  25. X
  26. Y
  27. Z
  28. #
 
    •  / 
    Zum Artikel