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.

The ?? operator, formally known as the if-null operator, is a binary, short-circuiting operator that evaluates and returns its left operand if it is not null; otherwise, it evaluates and returns its right operand.

Syntax

expression1 ?? expression2

Evaluation Mechanics

The operator follows a strict, lazy evaluation sequence:
  1. expression1 (the left operand) is evaluated.
  2. If the value of expression1 is non-null, the operator returns that value. expression2 (the right operand) is short-circuited and never evaluated.
  3. If the value of expression1 is null, expression2 is evaluated, and its resulting value is returned.
int? leftOperand = null;
int rightOperand = 10;

// Evaluates to 10 because leftOperand is null.
int result = leftOperand ?? rightOperand; 

Short-Circuiting Behavior

Because the operator short-circuits, any side effects or computationally expensive operations placed on the right-hand side will only execute if the left-hand side resolves to null.
int expensiveComputation() {
  // Simulating an expensive task
  return 100;
}

int? value = 5;

// The function expensiveComputation() is never invoked 
// because 'value' is already non-null.
int result = value ?? expensiveComputation();

Type Resolution

Dart’s sound null safety system applies specific static typing rules to the ?? operator. The static type of the expression e1 ?? e2 is determined by the least upper bound of the non-nullable type of e1 and the type of e2. Consequently, the resulting expression is non-nullable only if the right operand (e2) is non-nullable. If the right operand is a nullable type, the resulting expression remains nullable.
String? nullableString = null;
String nonNullableString = "Fallback";
String? anotherNullable = null;

// The compiler infers 'resolvedString' as the non-nullable type 'String'
// because the right operand is non-nullable.
String resolvedString = nullableString ?? nonNullableString;

// The compiler infers 'stillNullable' as the nullable type 'String?'
// because the right operand is nullable.
String? stillNullable = nullableString ?? anotherNullable;

Operator Precedence

The ?? operator has lower precedence than the logical OR operator (||) and higher precedence than the conditional ternary operator (?:). This dictates how unparenthesized complex expressions are parsed by the compiler.
bool? condition = null;
bool fallbackA = false;
bool fallbackB = true;

// '||' has higher precedence than '??'. 
// Parsed as: condition ?? (fallbackA || fallbackB)
bool result1 = condition ?? fallbackA || fallbackB;

// '??' has higher precedence than '?:'.
// Parsed as: (condition ?? fallbackB) ? "Yes" : "No"
String result2 = condition ?? fallbackB ? "Yes" : "No";

Operator Chaining

The ?? operator is left-associative and can be chained sequentially. A chained expression evaluates strictly from left to right, terminating and returning the first non-null value it encounters.
int? a = null;
int? b = null;
int c = 42;

// Evaluates 'a', then 'b', then 'c'. Returns 42.
int result = a ?? b ?? c;
Master Dart with Deep Grasping Methodology!Learn More