Patterns & Matching (3.0)
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 87 von 110.
Dart 3 führte Pattern Matching ein, eine leistungsstarke Methode, um Daten in einem einzigen Ausdruck zu destrukturieren und zu untersuchen. Patterns ermöglichen es Ihnen, Werte aus Objekten zu extrahieren, deren Struktur zu prüfen und Variablen zu binden – und das alles auf einmal.
Du hast bereits grundlegendes Destructuring mit Records gesehen. Patterns erweitern dies, um mit Objekten, Listen und Maps zu funktionieren:
void main() {
// Listen-Patterns
var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c'); // 1, 2, 3
// Map-Patterns
var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age'); // Alice is 30
}Patterns werden in switch-Ausdrücken besonders mächtig. Sie können gleichzeitig auf Typ, Wert und Struktur prüfen:
String describe(Object obj) {
return switch (obj) {
int n when n < 0 => 'Negative number',
int n => 'Positive number: $n',
String s => 'String of length ${s.length}',
[int first, ...] => 'List starting with $first',
_ => 'Something else',
};
}
void main() {
print(describe(-5)); // Negative Zahl
print(describe(42)); // Positive Zahl: 42
print(describe([1, 2, 3])); // Liste beginnend mit 1
}Die when-Klausel fügt Bedingungen zu Mustern hinzu, und ... gleicht verbleibende Elemente in einer Liste ab. Der Unterstrich _ fungiert als Platzhalter, der auf alles passt. In Kombination mit versiegelten Klassen ermöglichen Muster eine erschöpfende, typsichere Handhabung komplexer Datenstrukturen.
Aufgabe
EinfachLassen Sie uns einen Datenklassifizierer erstellen, der Pattern Matching verwendet, um verschiedene Arten von Eingaben zu analysieren und zu kategorisieren! Sie werden ein System erstellen, das verschiedene Datenstrukturen mithilfe der leistungsstarken Pattern-Matching-Funktionen von Dart 3 identifizieren und beschreiben kann.
Sie werden Ihren Code in zwei Dateien organisieren:
classifier.dart: Erstellen Sie eine Funktion namensclassify, die einenObject-Parameter entgegennimmt und eineString-Beschreibung zurückgibt. Verwenden Sie einen Switch-Ausdruck mit Pattern Matching, um diese Fälle zu behandeln:- Eine leere Liste
[]sollteEmpty listzurückgeben - Eine Liste mit genau einem Integer-Element sollte
Single item: [value]zurückgeben - Eine Liste mit genau zwei Elementen sollte
Pair: [first] and [second]zurückgeben - Eine Liste, die mit einem Integer beginnt, gefolgt von weiteren Elementen, sollte
List starting with [first], length: [total length]zurückgeben (verwenden Sie das...Rest-Pattern) - Eine Map, die sowohl die Schlüssel
'name'als auch'age'enthält, sollte[name] is [age] years oldzurückgeben (verwenden Sie Map-Pattern-Destructuring) - Ein Integer, der negativ ist (verwenden Sie die
when-Klausel), sollteNegative: [value]zurückgeben - Ein Integer, der Null ist, sollte
Zerozurückgeben - Jeder andere Integer sollte
Positive: [value]zurückgeben - Jeder andere Wert sollte
Unknown typezurückgeben
- Eine leere Liste
main.dart: Importieren Sie Ihren Klassifizierer und demonstrieren Sie Pattern Matching mit verschiedenen Eingaben. Geben Sie das Ergebnis der Klassifizierung für jeden dieser Werte aus:- Eine leere Liste
[] - Eine Liste mit einem Element:
[42] - Eine Liste mit zwei Elementen:
['hello', 'world'] - Eine längere Liste:
[1, 2, 3, 4, 5] - Eine Map:
{'name': 'Alice', 'age': 25} - Der Integer
-10 - Der Integer
0 - Der Integer
99
- Eine leere Liste
Diese Herausforderung kombiniert Listen-Patterns, Map-Patterns, die when-Klausel für Guards und das Rest-Pattern (...) – all die wichtigen Pattern-Matching-Funktionen aus der Lektion!
Erwartete Ausgabe:
Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99Spickzettel
Dart 3 hat Pattern Matching zum Destrukturieren und Inspizieren von Daten in einem einzigen Ausdruck eingeführt.
Listen-Pattern
Werte aus Listen extrahieren:
var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c'); // 1, 2, 3Map-Pattern
Maps nach Schlüsseln destrukturieren:
var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age'); // Alice is 30Switch-Ausdrücke mit Pattern
Abgleich nach Typ, Wert und Struktur:
String describe(Object obj) {
return switch (obj) {
int n when n < 0 => 'Negative number',
int n => 'Positive number: $n',
String s => 'String of length ${s.length}',
[int first, ...] => 'List starting with $first',
_ => 'Something else',
};
}Pattern-Features
when-Klausel: Fügt Bedingungen zu Pattern hinzu...(Rest-Pattern): Passt auf verbleibende Elemente in einer Liste_(Wildcard): Passt auf alles
Probier es selbst
import 'classifier.dart';
void main() {
// TODO: Verwende die classify Funktion, um jeden Wert zu kategorisieren
// und gib die Ergebnisse aus
// Teste mit einer leeren Liste
print(classify([]));
// TODO: Teste mit einer Liste, die ein Element enthält: [42]
// TODO: Teste mit einer Liste, die zwei Elemente enthält: ['hello', 'world']
// TODO: Teste mit einer längeren Liste: [1, 2, 3, 4, 5]
// TODO: Teste mit einer Map: {'name': 'Alice', 'age': 25}
// TODO: Teste mit dem Integer -10
// TODO: Teste mit dem Integer 0
// TODO: Teste mit dem Integer 99
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienBibliotheken & ImportsEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenInstanzvariablenKonstruktor-GrundlagenWiederholung – Einfacher Taschenrechner4Null-Sicherheit
Einführung in Null-SicherheitNullable vs. Non-NullableDie ? und ! OperatorenLate-Schlüsselwort & Null-SicherheitNull-aware OperatorenNull-Sicherheit in KlassenZusammenfassung – Benutzerprofil-System7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrfache InterfacesRückblick – Shape Calculator10Collections & Generics
Überblick über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische ConstraintsIterable & IteratorZusammenfassung – Generische Speicherung13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
Standard-KonstruktorBenannte KonstruktorenInitialisierungslistenKonstante KonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenZusammenfassung – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _ Präfix-KonventionSichtbarkeit auf Library-EbeneGetter & Setter im DetailInformation HidingRückblick – Schülerdatensätze8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas on-Schlüsselwort in MixinsMixin vs. VererbungMixin vs. InterfaceZusammenfassung - Tiersystem11Spezielle Methoden
toString() überschreibenhashCode & == überschreibenComparable-Interfacecall()-MethodenoSuchMethod überschreibenZusammenfassung – Eigene Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster3Klasseneigenschaften
Instanz- vs. statische MemberFinal & Const FelderLate-VariablenStatische Methoden & FelderGetter und SetterZusammenfassung – Bankkonto-Manager6Vererbung
Grundlagen der VererbungDas super-SchlüsselwortMethoden überschreibenDie @override-AnnotationDas final-Klassen-SchlüsselwortKonstruktoren & VererbungRückblick – Mitarbeiter-Hierarchie9Polymorphismus
Polymorphismus-GrundlagenPolymorphismus über InterfacesTypprüfung zur LaufzeitDie is & as OperatorenDas covariant SchlüsselwortZusammenfassung – Payment Processor