Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A map pattern is a destructuring and matching mechanism in Dart that asserts a value implements the Map interface, contains specific constant keys, and evaluates whether the values associated with those keys match defined subpatterns. Map patterns inherently perform partial matching. They only verify the presence and structure of explicitly declared keys, ignoring any additional key-value pairs present in the matched map object.

Syntax

The syntax consists of an optional type argument list followed by a comma-separated list of key-pattern pairs enclosed in curly braces.
<KeyType, ValueType>{key1: subpattern1, key2: subpattern2}
  • KeyType, ValueType: Optional type arguments to assert the exact map type.
  • key: A constant expression representing the map key.
  • subpattern: Any valid Dart pattern (variable, constant, relational, logical, etc.) applied to the value associated with the key.

Matching Mechanics

When a map pattern is evaluated against a value, Dart executes the following sequence:
  1. Type Assertion: Verifies the matched value implements Map<K, V>. If type arguments are omitted, Dart infers them from the matched value’s static type (e.g., matching against a variable typed as Map<String, int> infers <String, int>). It only falls back to Map<dynamic, dynamic> if the matched type does not provide specific type arguments (such as when matching against dynamic or Object).
  2. Key Presence: Verifies the map contains the exact keys specified in the pattern.
  3. Subpattern Evaluation: Extracts the value for each specified key and matches it against the corresponding subpattern.
If any of these steps fail, the entire map pattern fails to match.

Syntax Visualization

Variable Destructuring Map patterns can be used in variable declarations to extract values directly into local variables. When prefixing the declaration with final or var, the inner subpatterns bind directly to variable names without repeating the keyword.
final map = {'a': 1, 'b': 2, 'c': 3};

// Extracts the value of 'a' into x and 'b' into y.
// The key 'c' is ignored due to partial matching.
final {'a': x, 'b': y} = map; 
Pattern Matching in Control Flow Map patterns are utilized in switch statements and if-case constructs for structural validation.
void evaluateMap(dynamic input) {
  switch (input) {
    // Matches a Map<String, int> containing keys 'x' and 'y'
    case <String, int>{'x': final x, 'y': final y}:
      print('Matched typed map with x:$x, y:$y');
      
    // Matches any map containing key 'status' with value 200, 
    // and binds the value of 'body' to a typed variable.
    case {'status': 200, 'body': String body}:
      print('Matched untyped map with body:$body');
      
    // Matches if 'count' exists and its value is greater than 10
    case {'count': > 10}:
      print('Matched relational subpattern');
  }
}

Technical Constraints and Nuances

  • Constant Keys Required: The keys defined in a map pattern must be constant expressions at compile time. You cannot use variables evaluated at runtime as keys in the pattern.
const k = 'key';
final {k: value} = {'key': 1}; // Valid

var dynamicKey = 'key';
final {dynamicKey: value} = {'key': 1}; // Compile-time error
  • Non-Exhaustiveness: Map patterns are inherently non-exhaustive because a map might lack the required keys at runtime. Furthermore, by Dart’s language design, map patterns are never considered exhaustive by the compiler—even the empty map pattern {}, which matches any map, is treated as non-exhaustive. Therefore, when used in a switch expression, a default case (_) or a catch-all pattern is strictly required to satisfy the exhaustiveness checker.
  • Rest Elements Forbidden: Dart explicitly forbids the use of rest elements (...) within map patterns. Because map patterns inherently perform partial matching (ignoring unspecified keys), the language designers made it a compile-time error to include a rest element to prevent confusion. You cannot use a standalone rest element, nor can you bind a rest element to capture unmatched key-value pairs.
final map = {'a': 1, 'b': 2, 'c': 3};

// Both of the following result in a compile-time error:
// "Map patterns can't contain a rest pattern"
if (map case {'a': 1, ...}) {} 
if (map case {'a': 1, ...var rest}) {} 
Master Dart with Deep Grasping Methodology!Learn More