Patterns & Matching (3.0)
Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 87 of 110.
Dart 3 introduced pattern matching, a powerful way to destructure and inspect data in a single expression. Patterns let you extract values from objects, check their structure, and bind variables - all at once.
You've already seen basic destructuring with records. Patterns extend this to work with objects, lists, and maps:
void main() {
// List 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 become especially powerful in switch expressions. You can match on type, value, and structure simultaneously:
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 number
print(describe(42)); // Positive number: 42
print(describe([1, 2, 3])); // List starting with 1
}The when clause adds conditions to patterns, and ... matches remaining elements in a list. The underscore _ acts as a wildcard that matches anything. Combined with sealed classes, patterns enable exhaustive, type-safe handling of complex data structures.
Challenge
EasyLet's build a data classifier that uses pattern matching to analyze and categorize different types of input! You'll create a system that can identify and describe various data structures using Dart 3's powerful pattern matching features.
You'll organize your code into two files:
classifier.dart: Create a function calledclassifythat takes anObjectparameter and returns aStringdescription. Use a switch expression with pattern matching to handle these cases:- An empty list
[]should returnEmpty list - A list with exactly one integer element should return
Single item: [value] - A list with exactly two elements should return
Pair: [first] and [second] - A list starting with an integer followed by more elements should return
List starting with [first], length: [total length](use the...rest pattern) - A map containing both
'name'and'age'keys should return[name] is [age] years old(use map pattern destructuring) - An integer that is negative (use
whenclause) should returnNegative: [value] - An integer that is zero should return
Zero - Any other integer should return
Positive: [value] - Any other value should return
Unknown type
- An empty list
main.dart: Import your classifier and demonstrate pattern matching with various inputs. Print the result of classifying each of these values:- An empty list
[] - A list with one element:
[42] - A list with two elements:
['hello', 'world'] - A longer list:
[1, 2, 3, 4, 5] - A map:
{'name': 'Alice', 'age': 25} - The integer
-10 - The integer
0 - The integer
99
- An empty list
This challenge combines list patterns, map patterns, the when clause for guards, and the rest pattern (...) - all the key pattern matching features from the lesson!
Expected output:
Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99Cheat sheet
Dart 3 introduced pattern matching for destructuring and inspecting data in a single expression.
List Patterns
Extract values from lists:
var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c'); // 1, 2, 3Map Patterns
Destructure maps by key:
var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age'); // Alice is 30Switch Expressions with Patterns
Match on type, value, and structure:
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
whenclause: Adds conditions to patterns...(rest pattern): Matches remaining elements in a list_(wildcard): Matches anything
Try it yourself
import 'classifier.dart';
void main() {
// TODO: Use the classify function to categorize each value
// and print the results
// Test with an empty list
print(classify([]));
// TODO: Test with a list containing one element: [42]
// TODO: Test with a list containing two elements: ['hello', 'world']
// TODO: Test with a longer list: [1, 2, 3, 4, 5]
// TODO: Test with a map: {'name': 'Alice', 'age': 25}
// TODO: Test with the integer -10
// TODO: Test with the integer 0
// TODO: Test with the integer 99
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesLibraries & ImportsIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsInstance VariablesConstructor BasicsRecap - Simple Calculator4Null Safety
Intro to Null SafetyNullable vs Non-NullableThe ? and ! OperatorsLate Keyword & Null SafetyNull-Aware OperatorsNull Safety in ClassesRecap - User Profile System7Abstract Classes & Interfaces
Abstract ClassesAbstract MethodsInterfaces in DartImplicit InterfacesImplementing vs ExtendingMultiple InterfacesRecap - Shape Calculator10Collections & Generics
List, Set, Map OverviewType-Safe CollectionsGeneric ClassesGeneric MethodsGeneric ConstraintsIterable & IteratorRecap - Generic Storage13Advanced OOP Concepts
Composition vs InheritanceExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums with Methods16Project: Library Management
Project OverviewBook and User Classes2Constructors in Dart
Default ConstructorNamed ConstructorsInitializer ListsConstant ConstructorsFactory ConstructorsRedirecting ConstructorsRecap - Shape Builder5Encapsulation
Public vs Private MembersThe _ Prefix ConventionLibrary-Level PrivacyGetters & Setters DepthInformation HidingRecap - Student Records8Mixins
Introduction to MixinsCreating MixinsUsing Multiple Mixinson Keyword in MixinsMixin vs InheritanceMixin vs InterfaceRecap - Animal System11Special Methods
toString() OverridehashCode & == OverrideComparable Interfacecall() MethodnoSuchMethod OverrideRecap - Custom Collection14Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern3Class Properties
Instance vs Static MembersFinal & Const FieldsLate VariablesStatic Methods & FieldsGetters and SettersRecap - Bank Account Manager6Inheritance
Basic InheritanceThe super KeywordMethod OverridingThe @override AnnotationThe final Class KeywordConstructors & InheritanceRecap - Employee Hierarchy9Polymorphism
Polymorphism BasicsPolymorphism via InterfacesRuntime Type CheckingThe is & as OperatorsCovariant KeywordRecap - Payment Processor