dart-use-pattern-matching
Use switch expressions and pattern matching where appropriate
By flutter · 7,957 installs
npx skills add flutter/agent-plugins --skill dart-use-pattern-matching
Source repository · Upstream listing
Implementing Dart Patterns
Contents
[Pattern Selection Strategy]( pattern selection strategy)
[Switch Statements vs. Expressions]( switch statements vs expressions)
[Core Pattern Implementations]( core pattern implementations)
[Workflows]( workflows)
[Examples]( examples)
Pattern Selection Strategy
Apply specific pattern types based on the data structure and desired outcome. Follow these conditional guidelines:
If validating and extracting from deserialized data (e.g., JSON): Use Map and List patterns to simultaneously check structure and destructure key value pairs.
If handling multiple return values: Use Record patterns to destructure fields directly into local variables.
If executing type specific behavior (Algebraic Data Types): Use Object patterns combined with sealed classes to ensure exhaustiveness.
If matching numeric ranges or conditions: Use Relational ( = , <= ) and Logical and ( && ) patterns.
If multiple cases share logic: Use Logical or ( ) patterns to share a single case body or guard clause.
If ignoring specific values: Use the Wildcard pattern ( ) or a non matching Rest element ( ... ) in collections.
Switch Statements vs. Expressions
Select the appropriate switch construct based on the execution context:
If producing a value: Use a switch expression .
Syntax: switch (value) { pattern = expression, }
Rule: Each case must be a single expression. No implicit fallthrough. Must be exhaustive.
If executing statements or side effects: Use a switch statement .
Syntax: switch (value) { case pattern: statements; }
Rule: Empty cases fall through to the next case. Non empty cases implicitly break (no break keyword required).
Core Pattern Implementations
Implement patterns using the following syntax and rules:
Logical or ( ): pattern1 pattern2 . Both branches must define the exact same set of variables.
Logical and ( && ): pattern1 && pattern2 . Branches must not define overlapping variables.
Relational: == , != , < , , <= , = followed by a constant expression.
Cast ( as ): pattern as Type . Throws if the value does not match the type. Use to forcibly assert types during destructuring.
Null check ( ? ): pattern? . Fails the match if the value is null. Binds the variable to the non nullable base type.
Null assert ( ! ): pattern! . Throws if the value is null.
Variable: var name or Type name . Binds the matched value to a new local variable.
Wildcard ( ): Matches any value and discards it.
List: [pattern1, pattern2] . Matches lists of exact length unless a Rest element ( ... or ...var rest ) is used.
Map: {"key": pattern} . Matches maps containing the specified keys. Ignores unmatched keys.
Record: (pattern1, named: pattern2) . Matches records of the exact shape. Use :var name to infer the getter name.
Object: ClassName(field: pattern) . Matches instances of ClassName . Use :var field to infer the getter name.
Workflows
Task Progress: Implementing Pattern Matching
Copy this checklist to track progress when implementing complex pattern matching logic:
[ ] Identify the data structure being evaluated (JSON, Record, Class, Enum).
[ ] Select the appropriate switch construct (Expression for values, Statement for side effects).
[ ] Define the required patterns (Object, Map, List, Record).
[ ] Extract required data using Variable patterns ( var x , :var y ).
[ ] Apply Guard clauses ( when condition ) for logic that cannot be expressed via patterns.
[ ] Handle unmatched cases using a Wildcard ( ) or default clause (if not using a sealed class).
[ ] Run exhaustiveness validator.
Feedback Loop: Exhaustiveness Checking
When switching over sealed classes or enums, you must ensure all subtypes are handled.
1. Run validator: Execute dart analyze .
2. Review errors: Look for "The type 'X' is not exhaustively matched by the switch cases" errors.
3. Fix: Add the missing Object patterns for the unhandled subtypes, or add a Wildcard ( ) case if a default fallback is acceptable.
Examples
JSON Validation and Destructuring
Use Map and List patterns to validate structure and extract data in a single step.
Input:
Implementation:
Algebraic Data Types (Sealed Classes)
Use Object patterns with switch expressions to handle family types exhaustively.
Implementation:
Variable Swapping and Destructuring
Use variable assignment patterns to swap values or extract record fields without temporary variables.
Implementation:
Guard Clauses and Logical or
Use when to evaluate arbitrary conditions after a pattern matches.
Implementation: