Pattern

I. Logisches ODER-Muster A || B

Passt zu einem beliebigen Teilmuster; alle Zweige müssen identische Mengen von Variablen definieren.

enum Color { red, yellow, blue, green }
void main() {
  Color c = Color.red;
  bool primary = switch(c) {
    Color.red || Color.yellow || Color.blue => true,
    _ => false
  };
  print(primary); // true
}Code-Sprache: Dart (dart)

II. Logisches UND-Muster A && B

Beide Teilmuster müssen gleichzeitig passen; Teilmuster dürfen keine Variablen mit identischem Namen binden.

void main() {
  switch((2, 3)) {
    // Fehler: Beide Teilmuster binden Variable b, Namenskonflikt
    // case (var a, var b) && (var b, var c): print("ok");
    case (var a, var b) && (>1, <5):
      print("a=$a,b=$b"); // a=2,b=3
  }
}Code-Sprache: Dart (dart)

Das Muster (>1, <5) fordert, dass die erste Zahl größer als 1 und die zweite kleiner als 5 ist.

III. Relationales Muster < > <= >= == !=

Dient zur Prüfung numerischer Wertebereiche, häufig kombiniert mit && zur Eingrenzung von Wertegrenzen

String asciiCharType(int charCode) {
  const space = 32, zero = 48, nine = 57;
  return switch(charCode) {
    < space => "Steuerzeichen",
    == space => "Leerzeichen",
    > space && < zero => "Satzzeichen",
    >= zero && <= nine => "Ziffer",
    _ => "Sonstiges"
  };
}
void main() {
  print(asciiCharType(50)); // Ziffer
  print(asciiCharType(33)); // Satzzeichen
}Code-Sprache: Dart (dart)

Dieses Beispiel nutzt den ASCII-Code zur Einteilung von Steuerzeichen, Ziffern und Symbolen. Die Auswertungsregel für charCode im switch: unter 32 = Steuerzeichen, genau 32 = Leerzeichen, zwischen 32 und 48 = Satzzeichen, 48 bis einschließlich 57 = Ziffer, alle übrigen Werte fallen unter Sonstiges.

IV. Typumwandlungs-Muster sub as Type

Erzwingt eine explizite Typumwandlung während der Destrukturierung; bei Typunterschied wird eine Laufzeitausnahme ausgelöst

void main() {
  (num, Object) rec = (10, "hello");
  var (i as int, s as String) = rec;
  print(i + 5); // 15
  print(s.toUpperCase()); // HELLO
}Code-Sprache: Dart (dart)

In diesem Beispiel wird der Datensatz rec in i und s aufgeteilt. Ist das erste Element kein Integer oder das zweite keine Zeichenkette, tritt eine Laufzeitausnahme auf.

Siehe das fehlerhafte Beispiel unten:

void main() {
  (num, Object) rec = (9.3, "hello");
  var (i as int, s as String) = rec;
  print(i + 5); // 15
  print(s.toUpperCase()); // HELLO
}Code-Sprache: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
type 'double' is not a subtype of type 'int' in type cast
#0      main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:3:10)
#1      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code-Sprache: PHP (php)

V. Null-Prüf-Muster sub?

Passt nur bei nicht-null-Werten; innere Variablen werden automatisch zu nicht-null-Typen hochgestuft. Bei null schlägt der Abgleich fehl ohne Ausnahme.

void main() {
  String? str = "test";
  switch(str) {
    case var s?:
      print(s.length); // s ist nicht-null-Zeichenkette, Ausgabe 4
    case null:
      print("Null-Wert");
  }
}Code-Sprache: Dart (dart)

VI. Null-Behauptungs-Muster sub!

Passt nur bei nicht-null-Werten; ist der Wert null, wird sofort eine Laufzeitausnahme geworfen

void main() {
  List<String?> row = ["user", "bob"];
  switch(row) {
    case ["user", var name!]:
      print(name); // name ist nicht-null-Zeichenkette
  }

  // Nutzung bei Variablen-Destrukturierung
  (int?, int?) pos = (2, 3);
  var (x!, y!) = pos;
  print(x + y);
}Code-Sprache: Dart (dart)

Aufschlüsselung von var name!

  • var nameVariablenmustervar deklariert eine neue lokale Variable name und bindet den passenden Wert bei Erfolg;
  • !Nachgestelltes Null-Behauptungs-Muster — Erzwingt, dass der aktuelle Wert nicht null sein darf; bei null tritt ein Laufzeitfehler auf.

Kombinierte Bedeutung: var name! erstellt eine neue Variable name und stellt gleichzeitig sicher, dass der Wert niemals null ist.

VII. Konstanten-Muster

Literale, benannte Konstanten, Konstuktoren mit const und const-Sammlungen zählen zu Konstantenmustern; Übereinstimmung tritt bei identischen Werten ein

Unterstützte Typen: Zahlen, Zeichenketten, Wahrheitswerte, benannte Konstanten, const-Objekte / Listen

void main() {
  const target = 10;
  int num = 10;
  switch(num) {
    case 1: print("Eins");
    case target: print("Passt zur Konstante 10");
    case const [1,2]: print("Konstantenliste");
    default: print("Sonstiges");
  }
}Code-Sprache: Dart (dart)

Ausgabe des Programms

Passt zur Konstante 10

VIII. Variablen-Muster var x / int x / final x

Bindet eine neue lokale Variable bei erfolgreichem Abgleich; eine Typangabe prüft gleichzeitig den Werttyp

void main() {
  switch((99, "dart")) {
    case (int a, String b):
      print("$a $b"); // 99 dart
    case (int a, int b):
      print("Zwei numerische Werte");
  }
}Code-Sprache: Dart (dart)

IX. Bezeichner-Muster

Verhalten unterteilt sich in drei Kontexte:

  1. Deklarationskontext var (a,b):Erstellt neue Variablen
  2. Zuweisungskontext (a,b) = val:Überschreibt vorhandene Variablen
  3. Switch-Abgleichskontext:Wird als Konstante behandelt (außer _)
void main() {
  const c = 5;
  int val = 2;
  switch(val) {
    case c: print("Passt zur Konstante c");
    default: print("Kein Treffer"); // Diese Zeile wird ausgeführt
  }
}
Code-Sprache: Dart (dart)

X. Klammer-Muster (Teilmuster)

Passt die Priorität der Musteroperatoren an, um die Auswertungsreihenfolge von || und && abzugrenzen

void main() {
  bool x = true, y = true, z = false;
  bool test = switch(true) {
    (x || y) && z => true,
    _ => false
  };
  print(test); // false
}
Code-Sprache: Dart (dart)

XI. Listen-Muster

Passt zu List-Objekten und destrukturiert Elemente nach Position; unterstützt den Rest-Operator ... zum Erfassen beliebig vieler übriger Elemente

1. Einfacher Listenabgleich
void main() {
  const a = "a", b = "b";
  var arr = ["a", "b"];
  switch(arr) {
    case [a, b]: print("Treffer gefunden");
    default: print("Kein Treffer");
  }
}Code-Sprache: Dart (dart)
2. Rest-Operator für übrige Elemente
void main() {
  var [a, b, ...rest, c, d] = [1,2,3,4,5,6,7];
  print("$a $b $rest $c $d"); // 1 2 [3, 4, 5] 6 7
}
Code-Sprache: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
1 2 [3, 4, 5] 6 7Code-Sprache: CSS (css)

XII. Map-Muster {"schlüssel": TeilMuster}

Passt zu Map-Objekten und prüft nur angegebene Schlüssel; fehlt ein Zielschlüssel, wird StateError ausgelöst, nicht genannte Zusatzschlüssel werden ignoriert

void main() {
  var data = {"user": ["Lily", 13]};
  if(data case {"user": [String name, int age]}) {
    print("$name $age"); //Lily 13
  }
}Code-Sprache: JavaScript (javascript)

XIII. Datensatz-Muster (Record)

Zwei Varianten: Positionsdatensatz (p1,p2), benannter Datensatz (k:p1,k2:p2)

Kurzschreibweise :var verfügbar, um wiederholte Feldnamen auszulassen

void main() {
  // Destrukturierung Positionsdatensatz
  var (name, age) = ("Doug", 25);
  // Kurz-Destrukturierung benannter Felder
  final (:name, :age) = (name: "Tom", age: 18);
}
Code-Sprache: JavaScript (javascript)

XIV. Objekt-Muster Klasse(Eigenschaft: p)

Passt zu Objekten des festgelegten Typs und destrukturiert Getter-Eigenschaften; Kurzschreibweise :var nutzbar

class Point {
  final int x, y;
  Point(this.x, this.y);
}

void main() {
  Point p = Point(10, 20);
  var Point(:x, :y) = p;
  print("$x $y");
}
Code-Sprache: JavaScript (javascript)

XV. Platzhalter-Muster _

Passt zu jedem Wert ohne Variable zu binden; als Platzhalter verwendet oder um nur den Typ zu prüfen ohne Wert zu extrahieren

void main() {
  var arr = [1,2,3];
  var [_, mid, _] = arr;
  print(mid); // 2

  switch((10, "abc")) {
    case (int _, String _):
      print("Typabgleich erfolgreich");
  }
}Code-Sprache: JavaScript (javascript)

Pattern

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert