Open Source im professionellen Einsatz
Linux-Magazin 08/2015
645

Klassenlos

Rust 1.0 lässt das Konzept der Klassen wieder fallen. Anstelle von Klassendefinitionen arbeitet Version 1.0 mit benutzerdefinierten, zusammengesetzten Datentypen, die sie bei Bedarf um Methoden ergänzt. Das Schlüsselwort »struct« leitet zu Beginn von Listing 4 die Definition des benutzerdefinierten Datentyps »Container« ein. Eine Instanz von »Container« speichert dabei in Zeile 2 intern einen Vektor aus 64 Bit breiten Fließkommazahlen im Feld »content« .

Listing 4

Anwendungsdaten ohne Klassen (impl.rs)

01 struct Container {
02   content: Vec<f64>
03 }
04
05 impl Container {
06   fn print_content(&self) {
07     println!("Der Container speichert {} Floats", self.content.len());
08   }
09 }
10
11 fn main() {
12   let c = Container {
13      content: vec!(1.0, 2.0, 3.0)
14   };
15
16   c.print_content();
17 }

Der Block nach dem Schlüsselwort »impl« ab Zeile 5 definiert die zum Datentyp »Container« passende Methode, so etwa »print_content()« (Zeilen 6 bis 8). Sie übernimmt dank der Variablen »self« eine Referenz auf sich selbst.

Die Zeile danach gibt die Anzahl der in »content« gespeicherten Fließkommazahlen mit Hilfe des Makros »println« über die Standardausgabe in der Shell aus. Dabei formatiert sie das Ergebnis auch gleich. Bevor das Makro dies allerdings tut, ersetzt Rust den Platzhalter »{}« in der Zeichenkette durch den Wert des Methoden-Aufrufs »len« für den Vektor aus der Komponente »content« .

Im Hauptteil des Programms erzeugt Zeile 12 die Variable »c« vom Typ »Container« . Den Vektor, den die Komponente »content« speichert, erhält sie in Zeile 13 nach dem Doppelpunkt. Ihn erzeugt ebenfalls ein Makro. Zeile 16 bringt anhand der bekannten Punktnotation noch die Methode »print_content()« ins Spiel. Übersetzt ein Entwickler nun die Datei »impl.rs« über »rustc impl.rs« und führt diese anschließend aus, erscheint die Meldung »Der Container speichert 3 Floats« in der Shell.

Traits

Traits dienen der Code-Abstraktion über die Grenzen von Datentypen hinweg. Sie sorgen dafür, dass Entwickler generische Funktionen ähnlich wie die Typklassen aus der funktionalen Programmiersprache Haskell [5] nutzen.

Listing 5 erzeugt den Trait »Dimension« , der in Zeile 2 lediglich die Signatur »fn volume(&self) -> f64;« der Methode »volume()« festlegt. Implementierungen folgen in Zeile 9 für eine Kugel (Datentyp »Sphere« ) und in Zeile 15 für einen Würfel (Datentyp »Cube« ).

Listing 5

Körperberechnungen (trait.rs)

01 trait Dimension {
02   fn volume(&self) -> f64;
03 }
04
05 struct Sphere {
06   radius: f64
07 }
08
09 impl Dimension for Sphere {
10   fn volume(&self) -> f64 {
11     4.0/3.0 * std::f64::consts::PI * cubic(self.radius)
12   }
13 }
14
15 struct Cube {
16   side: f64
17 }
18
19 impl Dimension for Cube {
20   fn volume(&self) -> f64 {
21     cubic(self.side)
22   }
23 }
24
25 fn print_volume<T: Dimension>(obj: T) {
26   println!("Das Objekt hat das Volumen von {}", obj.volume());
27 }
28
29 fn cubic(x: f64) -> f64 {
30   x * x * x
31 }
32
33 fn main() {
34   print_volume(Sphere { radius: 1.0});
35   print_volume(Cube { side: 1.0 });
36 }

Die Signatur (Zeile 2) spielt eine Rolle, weil sie sich auf die Methode »volume()« auswirkt, die der Code ab Zeile 10 für den Datentyp »Sphere« definiert. Zeile 11 berechnet das Kugelvolumen und liest den benötigten Radius aus dem gleichnamigen Feld. Für den Datentyp »Cube« (Würfel) geht der Entwickler in den Zeilen 19 bis 23 analog vor.

Die Hauptroutine des Programms ab Zeile 33 ruft die generische Funktion »print_volume()« jeweils mit einem Wert für die Datentypen »Sphere« und »Cube« auf. Hierbei lässt sich jeder Wert übernehmen, dessen zugehörigen Datentyp der Trait »Dimension« implementiert. Um dies zu vereinbaren, nennt der Programmierer in Zeile 25 nach der abstrakten Typvariablen »T« und dem Doppelpunkt den Namen des Trait.

Ruft das Programm dann »print_volume()« auf, kommt die Methode »volume()« mit dem jeweils passenden Datentyp zum Einsatz. Das Ergebnis gibt wieder das Makro »println« aus.

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 1.20 bringt assoziierte Konstanten und sichert Cargo ab

    Entwickler können Structs, Traits und Enums ab Rust 1.20 Konstanten zuordnen und Cargo schützt seine Zugangsdaten besser.

  • 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.

comments powered by Disqus

Ausgabe 10/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

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