EMZETT.
Login

Pattern Matching (Mustervergleich)

Kurz: Pattern Matching prüft einen Wert gegen eine Reihe von Mustern und zerlegt ihn dabei gleich in seine Bestandteile – ein mächtiger Ersatz für lange if/else- und switch-Ketten.

Genauer: Muster können Konstanten, Typen, Listen, Tupel, Datensätze und verschachtelte Strukturen beschreiben, oft mit zusätzlichen Bedingungen (Guards). Besonders ausgeprägt ist es in Haskell, OCaml, F#, Erlang, Elixir, Scala und Rust; Python (match, 3.10), Java (Muster in switch), C#, Kotlin und JavaScript ziehen nach. Nicht zu verwechseln mit dem Textmustervergleich durch reguläre Ausdrücke.

Im Detail

def beschreibe(wert):
    match wert:
        case 0:
            return "null"
        case int(n) if n < 0:
            return f"negativ: {n}"
        case [x]:
            return f"Liste mit einem Element {x}"
        case [x, *rest]:
            return f"Liste, beginnt mit {x}, Rest {rest}"
        case {"name": name}:
            return f"Objekt mit Name {name}"
        case str():
            return "ein Text"
        case _:
            return "etwas anderes"
 
print(beschreibe([1, 2, 3]))            # Liste, beginnt mit 1, Rest [2, 3]
print(beschreibe({"name": "Mia"}))      # Objekt mit Name Mia
enum Form { Kreis(f64), Rechteck(f64, f64) }
 
fn flaeche(f: Form) -> f64 {
    match f {
        Form::Kreis(r) => 3.14159 * r * r,
        Form::Rechteck(b, h) => b * h,
    }
}
laenge :: [a] -> Int
laenge []     = 0
laenge (_:xs) = 1 + laenge xs

Vorteile

  • Vollständigkeitsprüfung: Bei enum/sealed-Typen warnt der Compiler, wenn ein Fall fehlt.
  • Lesbarkeit: Struktur und Zerlegung stehen an einer Stelle.
  • Weniger Fehler als manuelles Prüfen und Indexieren.

Kurse mit ausführlichen Beispielen: Haskell, OCaml, Rust und Erlang.

Siehe auch: Reguläre Ausdrücke, Enum, switch, Typsysteme