Direkt zum Hauptinhalt springen
eLearner.app
Modul 2 · Lektion 2 von 24/14 im Kurs~15 min
Lektionen des Moduls (2/2)

Pattern Matching, Option und Result

Rust besitzt einen extrem leistungsfähigen Ablaufsteuerungsmechanismus namens Pattern Matching (Musterabgleich). Er ermöglicht es, einen Wert mit einer Reihe von Mustern zu vergleichen und Code basierend auf dem übereinstimmenden Muster auszuführen.

Die match-Anweisung

Die match-Anweisung in Rust ähnelt dem switch in anderen Sprachen, ist aber viel leistungsfähiger und sicherer. Der Compiler garantiert, dass das Matching exhaustiv (vollständig) ist, was bedeutet, dass alle möglichen Fälle behandelt werden müssen:

Code
enum Direction {
    North,
    South,
    East,
    West,
}

let dir = Direction::East;

match dir {
    Direction::North => println!("Andiamo a Nord"),
    Direction::South => println!("Andiamo a Sud"),
    Direction::East => println!("Andiamo a Est"),
    Direction::West => println!("Andiamo a Ovest"),
}

Umgang mit dem Fehlen von Werten: Option

Rust kennt kein Konzept für Nullwerte (null oder nil). Stattdessen definiert die Standardbibliothek ein Enum namens Option<T>, das Folgendes enthalten kann:

  • Some(T): Enthält einen Wert vom Typ T.
  • None: Zeigt das Fehlen eines Wertes an.
Code
let x: Option<i32> = Some(5);
let y: Option<i32> = None;

match x {
    Some(val) => println!("C'e un valore: {}", val),
    None => println!("Nessun valore trovato"),
}

Umgang mit behebbaren Fehlern: Result

Für Operationen, die fehlschlagen können (wie das Lesen einer Datei oder das Konvertieren eines Strings in eine Zahl), verwendet Rust das Enum Result<T, E>, das zwei Varianten besitzt:

  • Ok(T): Die Operation war erfolgreich und enthält den Erfolgswert T.
  • Err(E): Die Operation ist fehlgeschlagen und enthält den Fehler E.
Code
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
    if denominator == 0.0 {
        Err(String::from("Divisione per zero!"))
    } else {
        Ok(numerator / denominator)
    }
}

Dank des Rust-Compilers sind Sie gezwungen, den Fall Err zu behandeln, bevor Sie auf den Wert in Ok zugreifen können. Dies verhindert viele Fehler zur Laufzeit.

Das Platzhalter-Muster _ (Wildcard)

Wenn wir mit Datentypen arbeiten, die eine große Anzahl von Varianten haben (wie Ganzzahlen), ist es unmöglich, alle Fälle in einem match aufzulisten. Rust ermöglicht die Verwendung des Platzhalters _, um alle verbleibenden Fälle abzufangen, die nicht explizit definiert sind:

Code
let some_u8 = 3u8;
match some_u8 {
    1 => println!("Uno"),
    2 => println!("Due"),
    _ => println!("Qualcos'altro"), // Gestisce tutti gli altri valori
}

Probiere es aus

Übung#rust.m2.l2.e1
Versuche: 0Wird geladen…

Deklarieren Sie eine Variable maybe_value vom Typ Option<i32>, die Some(42) enthält. Verwenden Sie eine match-Anweisung auf maybe_value: Wenn sie Some(v) enthält, geben Sie 'value is: v' aus (mit println!), wenn sie None enthält, geben Sie 'no value' aus.

Editor wird geladen…
Hinweis anzeigen

Schreiben Sie einen Block `match maybe_value { Some(v) => println!('value is: {}', v), None => println!('no value') }`.

Lösung nach 3 Versuchen verfügbar

Übung#rust.m2.l2.e2
Versuche: 0Wird geladen…

Vervollständigen Sie die Funktion check_age so, dass sie Ok('Adult') zurückgibt, wenn age größer oder gleich 18 ist, andernfalls Err('Minor').

Editor wird geladen…
Hinweis anzeigen

Verwenden Sie ein `if age >= 18`, um zu entscheiden, ob `Ok('Adult')`oder`Err('Minor')` zurückgegeben werden soll.

Lösung nach 3 Versuchen verfügbar

Übung#rust.m2.l2.e3
Versuche: 0Wird geladen…

Deklarieren Sie ein Enum namens Status mit den Varianten Active und Inactive. Deklarieren Sie in der main-Methode eine Variable current_status mit dem Wert Status::Active. Verwenden Sie schließlich eine match-Anweisung auf current_status, um 'active' auszugeben, wenn der Status Active ist, oder 'inactive', wenn der Status Inactive ist.

Editor wird geladen…
Hinweis anzeigen

Definieren Sie das Enum vor der main-Methode mit `enum Status { Active, Inactive }`. Verwenden Sie in main `let current_status = Status::Active;`und führen Sie den`match` auf den Varianten aus.

Lösung nach 3 Versuchen verfügbar