Pattern Matching in Rust ermöglicht es, Werte gemäß ihrer Struktur zu zerlegen, komplexe Typen mit den Konstruktionen match, if let, while let zu analysieren und zu verarbeiten. Destrukturierung ist nützlich für die Arbeit mit Tupeln, Strukturen, Enums und sogar Referenzen.
Beispiel mit Enum:
enum Message { Quit, ChangeColor(i32, i32, i32), Write(String), } let m = Message::ChangeColor(255, 0, 0); match m { Message::Quit => println!("Quit!"), Message::ChangeColor(r, g, b) => println!("Farbe: {} {} {}", r, g, b), Message::Write(text) => println!("Text: {}", text), }
Destrukturierung von Strukturen:
struct Point { x: i32, y: i32 } let p = Point { x: 10, y: 20 }; let Point { x, y } = p;
Feinheiten:
ref und ref mut ermöglicht es, Referenzen beim Zerlegen zu erhalten.@ kann man einen Teil des Musters "umbenennen".if guard).&SomeType) ist es wichtig, an Besitz und Borrowing zu denken.Kann man immer "_" (Unterstrich) verwenden, um Teile des Musters zu ignorieren und Compilerwarnungen zu vermeiden?
Nicht immer. Der Unterstrich überspringt zwar den Wert, aber wenn man nicht alle Varianten eines Enums verarbeitet und "_" für catch-all verwendet, kann man die Behandlung neuer Varianten beim Erweitern des Enums in der Zukunft verpassen. Es ist besser, immer explizit die wichtigen Varianten aufzulisten, damit der Compiler auf nicht berücksichtigte Fälle hinweist!
match result { Ok(val) => ..., Err(err) => ..., //_ => ... // nicht empfohlen für Enums! }
Geschichte
In einer IoT-Anwendung hörte das Gerät auf zu antworten, weil beim Hinzufügen einer neuen Variante zum Enum an der Stelle des Pattern Matchings ein catch-all "_" verwendet wurde. Der Fehler blieb bis zur Bereitstellung unsichtbar. Danach wurden kritische Enums immer nur durch explizites Auflisten der Varianten verarbeitet.
Geschichte
Für eine komplexe Struktur mit verschachtelten Tupeln wurde vergessen, die Syntax zur Destrukturierung rekursiver Felder hinzuzufügen, und anstelle von Referenzen wurden große Objekte versehentlich kopiert, was zu Leistungsproblemen führte.
Geschichte
In einem funktionalen Nachrichtenübertragungsteil zwischen Threads wurde die Destrukturierung mit if-let verwendet, aber seltene Varianten des Enums wurden ignoriert. Mit dem Auftreten neuer Geschäftslogik gingen Nachrichten einfach verloren. Danach wurde im Teamstil eine Regel festgelegt — jedes match-Ausdruck muss erschöpfend ohne catch-all sein.