====== Lyx – Pattern Matching (match) ======
Das ''match''-Statement ist eines der mächtigsten Kontrollfluss-Elemente in Lyx. Es erlaubt den Vergleich eines Wertes gegen eine Reihe von Mustern (Patterns). Im Gegensatz zu ''switch'' in C oder Java ist ''match'' in Lyx **typsicher** und **exhaustiv** (vollständig).
===== 1. Grundlegende Syntax =====
Ein ''match''-Block prüft einen Ausdruck und führt den ersten passenden Arm aus.
match (error_code) {
case 0 => { PrintStr("OK"); }
case 404 => { PrintStr("Not Found"); }
case 500 => { PrintStr("Server Error"); }
default => { PrintStr("Unknown Error"); }
}
* **=> (Fat Arrow)**: Trennt das Muster vom auszuführenden Code-Block.
* **default**: Der Auffang-Arm (Catch-all), falls kein anderes Muster passt.
===== 2. Matching auf Enums =====
Besonders stark ist ''match'' in Verbindung mit Aufzählungstypen (Enums). Der Compiler prüft hierbei die **Exhaustivität**.
enum FlightState { Idle, Taxiing, InAir, Landing }
fn handle_state(s: FlightState) {
match (s) {
case FlightState.Idle => { stop_engines(); }
case FlightState.Taxiing => { check_flaps(); }
case FlightState.InAir => { retract_gear(); }
case FlightState.Landing => { deploy_gear(); }
// Kein 'default' nötig, da alle Enum-Werte abgedeckt sind!
}
}
> **Compiler-Garantie:** Wenn du einen neuen Wert zum Enum ''FlightState'' hinzufügst, ohne das ''match'' zu aktualisieren, wirft der Compiler einen Fehler (**Inexhaustive Match**). Dies ist eine wichtige Sicherheitsfunktion für [[lyx_-_programmiersprache:do-178c|DO-178C]].
===== 3. Range-Matching =====
In Lyx können auch Wertebereiche direkt in den Cases geprüft werden. Dies ist besonders nützlich für die Auswertung von Sensordaten.
match (altitude) {
case 0..500 => { set_mode(Landing); }
case 501..30000 => { set_mode(Cruise); }
case 30001.. => { set_mode(HighAltitude); }
default => { panic("Invalid altitude"); }
}
===== 4. Typ-Deconstruction (v0.7.x+) =====
Lyx erlaubt das "Hineinschauen" in komplexe Strukturen (Deconstruction), um direkt auf deren Felder zu matchen.
type Event = struct { id: int, active: bool }
fn process(e: Event) {
match (e) {
case Event { id: 1, active: true } => { start_system(); }
case Event { active: false } => { log_inactive(); }
default => { ignore(); }
}
}
===== 5. Vergleich: match vs. if-else =====
^ Feature ^ match ^ if-else ^
| **Lesbarkeit** | Hoch bei vielen Fällen | Hoch bei einfachen Bedingungen |
| **Vollständigkeit** | Vom Compiler erzwungen | Manuell (Fehleranfällig) |
| **Performance** | Optimiert via Jump-Table | Lineare Prüfung (langsam) |
| **Komplexität** | Unterstützt Deconstruction | Nur boolesche Logik |
===== 6. Best Practices =====
* **Vermeide riesige default-Blöcke**: Versuche lieber, alle Fälle explizit zu benennen, um vom Compiler gewarnt zu werden, wenn sich die Logik ändert.
* **Nutze Blöcke**: Auch wenn ein Case nur eine Zeile hat, erhöhen geschweifte Klammern ''{ }'' die Wartbarkeit im Aerospace-Umfeld.
* **Range-Checks**: Nutze Ranges (''0..100'') statt komplexer Vergleiche (''x >= 0 && x <= 100''), da der Compiler diese besser optimieren kann.