Musterhaft und klassenlos

Rust bedient sich ausgiebig beim Repertoire anderer Sprachen. So verwendet sie wie die funktionalen Programmiersprachen Haskell und Standard ML 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.

Stellenmarkt
  1. Funktionsentwickler (w|m|d) Elektronik Automotive
    SALT AND PEPPER Technology GmbH & Co. KG, Ratingen
  2. (Fach-)Informatiker/IT-Syste- mkaufmann (m/w/d) System- / Anwendungsbetreuung
    Salamander Deutschland GmbH & Co KG, Wuppertal
Detailsuche

Der Match-Ausdruck im nächsten Code 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.

Mustererkennung

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

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 des folgenden Beispiels 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.

Golem Akademie
  1. ITIL 4® Foundation: virtueller Zwei-Tage-Workshop
    16.–17. Dezember 2021, virtuell
  2. Terraform mit AWS: virtueller Zwei-Tage-Workshop
    14.–15. Dezember 2021, Virtuell
Weitere IT-Trainings

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 sie 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 nutzen können.

Der folgende Code 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).

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 wird in den Zeilen 19 bis 23 analog vorgegangen.

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, wird in Zeile 25 nach der abstrakten Typvariablen T und dem Doppelpunkt der Name des Trait genannt.

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.

Bitte aktivieren Sie Javascript.
Oder nutzen Sie das Golem-pur-Angebot
und lesen Golem.de
  • ohne Werbung
  • mit ausgeschaltetem Javascript
  • mit RSS-Volltext-Feed
 Mozillas Programmiersprache: Rust bedient sich bei der KonkurrenzMakros, Cargo und Ausblick 
  1.  
  2. 1
  3. 2
  4. 3
  5.  


Baron Münchhausen. 19. Jul 2015

Deswegen hat er auch "war" hinzugefügt :)

grorg 18. Jul 2015

Wenn du damit auf das "Zitat" von Bill Gates ansprichst - das gab es nie und ist frei...

grorg 18. Jul 2015

Wir reden hier über eine Programmiersprache und nicht Picasso ....... zeig doch mal, wie...

esgeh 17. Jul 2015

In Rust wird dir genausowenig wie in C eine "Indirektion" aufgezwungen. Wenn du...

flasherle 17. Jul 2015

nur das bei reeller umsetzung das ganze durch die namensgebung leicht lesbar wird...



Aktuell auf der Startseite von Golem.de
Softwarepatent
Uraltpatent könnte Microsoft Millionen kosten

Microsoft hat eine Klage um ein Software-Patent vor dem BGH verloren. Das Patent beschreibt Grundlagentechnik und könnte zahlreiche weitere Cloud-Anbieter betreffen.
Ein Bericht von Stefan Krempl

Softwarepatent: Uraltpatent könnte Microsoft Millionen kosten
Artikel
  1. Amazon: Fire TV Stick 4K Max erhält erweiterte Heimkinofunktion
    Amazon
    Fire TV Stick 4K Max erhält erweiterte Heimkinofunktion

    Mit einem geplanten Update kann der Fire TV Stick 4K Max den Klang anderer Zuspielgeräte auf Echo-Lautsprechern ausgeben.

  2. Krypto: Angeblicher Nakamoto darf 1,1 Millionen Bitcoin behalten
    Krypto
    Angeblicher Nakamoto darf 1,1 Millionen Bitcoin behalten

    Ein Gericht hat entschieden, dass Craig Wright der Familie seines Geschäftspartners keine Bitcoins schuldet - kommt jetzt der Beweis, dass er Satoshi Nakamoto ist?

  3. Ladeinfrastruktur: Elektroauto-Laden soll barrierefrei werden
    Ladeinfrastruktur
    Elektroauto-Laden soll barrierefrei werden

    Der Umstieg auf Elektroautos geht einher mit dem Bau zahlreicher neuer Ladestationen. Diese sollen barrierefrei werden.

Du willst dich mit Golem.de beruflich verändern oder weiterbilden?
Zum Stellenmarkt
Zur Akademie
Zum Coaching
  • Schnäppchen, Rabatte und Top-Angebote
    Die besten Deals des Tages
    Daily Deals • Kingston PCIe-SSD 1TB 69,90€ & 2TB 174,90€ • Samsung Smartphones & Watches günstiger • Saturn-Advent: Xiaomi Redmi Note 9 Pro 128GB 199€ • Alternate (u. a. Razer Opus Gaming-Headset 69,99€) • Release heute: Halo Infinite 68,99€ • MM-Aktion: 3 Spiele kaufen, nur 2 bezahlen [Werbung]
    •  /