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 variable pattern binds a matched value to a newly declared variable. It acts as a wildcard that matches a value and simultaneously introduces a new identifier into the current lexical scope, allowing the matched value to be referenced within the pattern’s execution branch. Context-Dependent Syntax The syntax and rules for variable patterns depend strictly on whether they are used in a declaration context or a matching context. 1. Declaration Contexts In a pattern variable declaration statement, the mutability keyword (var or final) must be applied to the entire pattern at the top level. Individual elements within the declaration cannot have their own var, final, or explicit type annotations.
// Valid: Top-level 'var' applies to all variables in the list pattern.
var [first, second] = [10, 20];

// Valid: Top-level 'final' applies to all variables in the record pattern.
final (x, y) = (1.5, 2.5);
2. Matching Contexts In matching contexts (such as switch cases or if-case statements), variable patterns can be defined individually on specific elements using var, final, or an explicit type annotation.
// Inferred type, mutable binding
var identifier

// Inferred type, immutable binding
final identifier

// Explicit type, mutable binding
Type identifier
Binding Mechanics When a variable pattern evaluates a value, it extracts that value and binds it to the specified identifier. The static type of the bound variable is inferred from the matched value’s static type unless explicitly annotated. Variable patterns are frequently nested inside destructuring patterns (such as record, list, map, or object patterns) to extract specific sub-components of a larger data structure.
switch (record) {
  // 'a' and 'b' are variable patterns nested within a record pattern.
  // They bind the positional fields of the evaluated record to local variables.
  // Mixing 'var' and 'final' is permitted here because this is a matching context.
  case (var a, final b):
    print(a);
    print(b);
}
Refutability and Type Testing The refutability of a variable pattern depends entirely on its declaration syntax within a matching context:
  • Irrefutable (var / final): Patterns declared without an explicit type are irrefutable. They unconditionally match any value passed to them.
  • Refutable (Explicitly Typed): When an explicit type is provided (e.g., String s), the variable pattern implicitly functions as a type test pattern. It becomes refutable and will only match if the runtime type of the evaluated value is a subtype of the specified type. If the type test fails, the pattern rejects the value, and the variable is not bound.
switch (value) {
  // Refutable: Matches and binds ONLY if 'value' is a String.
  case String s:
    print(s.length);
  // Irrefutable: Matches any remaining value and binds it to 'v'.
  case var v:
    print(v);
}
Lexical Scope The scope of the identifier created by a variable pattern is dictated by its execution context:
  • Pattern variable declarations: The variable is available in the surrounding block scope.
  • Switch cases and if-case statements: The variable is available within the optional when guard clause and the corresponding case body. It is not available in subsequent cases.
Constraints in Logical-OR Patterns When variable patterns are utilized within a logical-OR pattern (||), Dart enforces strict binding rules. The variable must be declared in all branches of the OR pattern, and it must possess the exact same identifier and static type in every branch. This ensures the variable is safely initialized regardless of which branch succeeds.
switch (shape) {
  // The variable pattern 'size' is valid because it is bound 
  // on both the left and right sides of the logical-OR.
  case Square(length: var size) || Circle(radius: var size):
    print(size);
}
Master Dart with Deep Grasping Methodology!Learn More