Skip to main content
The ?: operator, formally known as the conditional operator or ternary operator, is an expression-based control flow construct in Dart. It evaluates a boolean condition and returns the result of one of two subsequent expressions based on that boolean value, effectively acting as a single-line, expression-level if-else statement.
condition ? consequentExpression : alternativeExpression
Mechanics and Evaluation
  1. The condition is evaluated first. In Dart’s sound null safety system, this expression must strictly evaluate to a type of bool.
  2. If the condition evaluates to true, the consequentExpression is evaluated, and its result becomes the value of the entire ternary operation.
  3. If the condition evaluates to false, the alternativeExpression is evaluated, and its result becomes the value of the entire ternary operation.
Short-Circuit Behavior The operator employs short-circuit evaluation. Dart guarantees that only one of the two result expressions is evaluated at runtime. The expression not selected by the condition is completely ignored, preventing any side effects (such as function calls or variable mutations) associated with the unselected branch from executing. Type Resolution The static return type of the ?: operation is determined by the least upper bound (LUB) of the static types of the consequentExpression and the alternativeExpression.
void main() {
  int x = 5;
  int y = 10;
  // Both expressions are of type 'int'. The resulting type is 'int'.
  int result = (x > y) ? x : y; 
  print(result); // Outputs: 10

  bool isInteger = true;
  // Expressions are 'int' and 'double'. The resulting type is 'num' (the LUB).
  num numericResult = isInteger ? 10 : 10.5; 
  print(numericResult); // Outputs: 10
}
Associativity and Evaluation Order The conditional operator is right-associative in its syntax parsing. When multiple ?: operators are chained without explicit parentheses, the syntax tree groups them from right to left. However, runtime evaluation strictly occurs left-to-right. The leftmost condition is evaluated first, and short-circuiting dictates whether the nested rightward expressions are evaluated at all.
// Syntax structure of chained ternary operators
condition1 ? expression1 : condition2 ? expression2 : expression3

// Implicit right-to-left grouping (parsing)
condition1 ? expression1 : (condition2 ? expression2 : expression3)
Cascade Operator Restriction In Dart’s formal grammar, the branches of the conditional operator expect an expressionWithoutCascade. Consequently, using an unparenthesized cascade operator (.. or ?...) inside a ternary operation results in a syntax error. To use a cascade within the consequentExpression or alternativeExpression, the cascade operation must be explicitly wrapped in parentheses.
class Builder {
  int value = 0;
  void increment() {
    value++;
  }
}

void main() {
  bool condition = true;
  Builder obj = Builder();
  Builder alternative = Builder();

  // Syntax Error: The parser expects an expressionWithoutCascade
  // var errorResult = condition ? obj..increment() : alternative;

  // Correct: Wrapping the cascade in parentheses resolves the grammar conflict
  var result = condition ? (obj..increment()) : alternative;
  
  print(result.value); // Outputs: 1
}
Tired of Poor Dart Skills? Fix That With Deep Grasping!Learn More