Dart - Operator Precedence and Associativity

This article contains a table and explanation about operator precedence level and associativity in Dart. This also applies for all Dart frameworks including Flutter.

There can be multiple operators in an expression. Dart has some rules to determine which operator should be executed first. In general, operators are executed according to their precedence level and associativity. This article explains how Dart determines the execution order if there are some operators in an expression.

Operator Precedence and Associativity Table

Below is the operator precedence and associativity table of Dart. Operators are executed according to their precedence level. If two operators share an operand, the operator with higher precedence will be executed first. If the operators have the same precedence level, it depends on the associativity. Both the precedence level and associativity can be seen in the table below.

Level Category Operator Associativity
16 Unary Postfix expr.
expr?.
expr++
expr--
expr1[expr2]
expr()
 
15 Unary Prefix -expr
!expr
++expr
--expr
~expr
await expr
 
14 Multiplicative *
/
~/
%
Left-to-right
13 Additive +
-
Left-to-right
12 Shift <<
>>
>>>>
Left-to-right
11 Bitwise AND & Left-to-right
10 Bitwise XOR ^ Left-to-right
9 Bitwise OR Postrix | Left-to-right
8 Relational and Test Type <
>
<=
>=
as
is
is!
 
7 Equality ==
!=
 
6 Logical AND && Left-to-right
5 Logical OR || Left-to-right
4 If null expr1 ?? expr2 Left-to-right
3 Conditional expr ? expr1 : expr2 Right-to-left
2 Cascade .. Left-to-right
1 Assignment =
*=
/=
+=
-=
&=
^=
<*lt;=
>>=
??=
~/=.
|=
%=
Right-to-left

Precedence Level

Below is an example of how precedence level determines the order. There are three operators =, +, and *.

  int result = (1 + 2) * 3;
  print(result); // 9

Because * has a higher precedence level (14) than + (13), the * operator will be executed before + operator. The = (assignment) operator has the lowest precedence among them (1), so it will be executed last. Therefore, the expression on the right hand side of the = operator is equivalent to 1 + (2 * 3). First, Dart will execute 2 * 3, which yields 6. Then it executes 1 + 6, which yields 7. At last, the result is assigned to the result variable.

Associativity

If there are more than one operators with the same precedence level, Dart will use the associativity of the operator. The table above has a column named associativity. If the associativity is left-to-right the leftmost operator will run first, followed by the next operators from left-to-right. If the associativity is right-to-left the rightmost operator will run first, followed by the next operators from right-to-left.

The example below uses two % in an expression.

  int result = 25 % 3 % 2;
  print(result); // 1

Since the associativity of % is left-to-right, 25 % 3 will be executed first. The result (1) will be used by the second % operator which computes 1 % 2.

The next example contains two = operators.

  int x = 1;
  int y = 2;
  int z = 3;

  x = y = z;

  print(x); // 3
  print(y); // 3
  print(z); // 3

Because the associativity is right-to-left, y = z will be executed first which means the value of z (3) will be assigned to y. After that, the value of y (after assigned with the value of z) will be assigned to x.

Overriding Precedence

What if you want to override the precedence of two operators. For example, an expression has addition and multiplication operators. By default, the multiplication operator runs first. If you want to run the addition operator first, you can use parentheses.

  int result = (1 + 2) * 3;
  print(result); // 9

With parentheses, 1 + 2 will be executed first and the result (3) will be multiplied by 3 afterwards.

Summary

Like other programming languages, Dart also has rules for determining the order of operator executions in an expression. The precedence level is used first. If some operators share the same precedence level, the associativity will be used. You can bookmark this page and refer to the table above when you forget.