Dart Operators
last modified June 4, 2025
This tutorial explores Dart operators, demonstrating how they are used to create expressions for processing data.
An operator is a symbol that triggers a specific operation on its operands. Inspired by mathematics, operators in programming manipulate data. An operand is an input to an operator, typically a value or variable.
Expressions combine operands and operators, with the operators defining the operations to perform. The evaluation order is governed by operator precedence and associativity, ensuring predictable results.
Operators are classified by the number of operands they take. Unary
operators use one operand, while binary operators use two.
Some operators, like +
, are overloaded, performing
different tasks (e.g., adding numbers or concatenating strings) based on
context.
Dart Minus Sign Operator
The minus sign operator -
negates a value, reversing its sign.
void main() { int a = 1; print(-a); print(-(-a)); }
This example shows the minus sign operator negating a value and then reversing it back to its original sign.
$ dart main.dart -1 1
Dart Assignment Operator
The assignment operator =
stores a value in a variable. Unlike
in mathematics, where =
denotes equality, in programming it
assigns the right-side value to the left-side variable.
int x = 1;
This assigns the value 1 to the variable x
.
x = x + 1;
This increments x
by 1, resulting in x
equaling 2.
Such expressions are valid in programming but not in mathematics.
3 = x;
This is invalid, as literals like 3 cannot be assigned values, causing a syntax error.
Dart's null-aware assignment operator ??=
assigns a value to a
variable only if it is null
, ensuring safe initialization.
void main() { int? x; x ??= 6; print(x); x ??= 3; print(x); }
Since x
is initially null
, 6 is assigned. The
second assignment is ignored because x
is no longer
null
.
$ dart main.dart 6 6
Dart Increment and Decrement Operators
The increment (++
) and decrement (--
) operators
add or subtract 1 from a variable, offering a concise way to update values.
void main() { var x = 6; x++; x++; print(x); x--; print(x); }
This example increments x
twice from 6 to 8, then decrements
it to 7, demonstrating both operators.
$ dart main.dart 8 7
These operators can be prefix or postfix, affecting when the value is updated relative to its use, which may lead to subtle differences in behavior.
void main() { var r1 = increase(3); print(r1); var r2 = increase2(3); print(r2); } int increase(int x) { return ++x; } int increase2(int x) { return x++; }
The prefix ++x
increments before returning, yielding 4. The
postfix x++
returns the original value before incrementing,
yielding 3.
$ dart main.dart 4 3
Dart Compound Assignment Operators
Compound assignment operators combine an operation with assignment, providing a shorthand for common updates like addition or multiplication.
a = a + 3; a += 3;
Both expressions add 3 to a
, with +=
being the
shorthand form. Other compound operators include -=
,
*=
, /=
, ~/=
, %=
,
&=
, |=
, ^=
, <<=
, and
>>=
.
void main() { var a = 1; a = a + 1; print(a); a += 5; print(a); a *= 3; print(a); }
This example shows standard addition, followed by compound addition and
multiplication, resulting in a
being updated to 2, 7, and 21.
$ dart main.dart 2 7 21
Dart Arithmetic Operators
Arithmetic operators perform mathematical operations on numeric operands, including addition, subtraction, multiplication, and division.
Symbol | Name |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
~/ | Integer division |
% | Remainder |
The table above lists the arithmetic operators in Dart
void main() { var a = 10; var b = 11; var c = 12; var add = a + b + c; var sb = c - a; var mult = a * b; var div = c / 3; var rem = c % a; print(add); print(sb); print(mult); print(div); print(rem); }
This example demonstrates addition, subtraction, multiplication, division,
and remainder operations, with %
computing the modulo (e.g., 12
% 10 = 2).
$ dart main.dart 33 2 110 4.0 2
The /
operator returns a double, while ~/
returns
an integer, distinguishing floating-point and integer division.
void main() { var c = 5 / 2; print(c); var d = 5 ~/ 2; print(d); }
This shows /
returning 2.5 (double) and ~/
returning 2 (integer) for 5 divided by 2.
$ dart main.dart 2.5 2
Dart Boolean Operators
Boolean operators, also called logical operators, manipulate boolean values to control program flow, often in conditional statements.
Symbol | Name |
---|---|
&& | Logical AND |
|| | Logical OR |
! | Negation |
The table above lists the boolean operators in Dart.
void main() { var x = 3; var y = 8; print(x == y); print(y > x); if (y > x) { print("y is greater than x"); } }
This example uses comparison operators to produce boolean results, which
drive an if
statement, printing a message when true.
$ dart main.dart false true y is greater than x
The logical AND (&&
) operator returns true only if both
operands are true.
void main() { var a = true && true; var b = true && false; var c = false && true; var d = false && false; print(a); print(b); print(c); print(d); }
This demonstrates &&
, with only the first case yielding true.
$ dart main.dart true false false false
The logical OR (||
) operator returns true if at least one
operand is true.
void main() { var a = true || true; var b = true || false; var c = false || true; var d = false || false; print(a); print(b); print(c); print(d); }
Three of the four cases yield true, as only both false operands result in false.
$ dart main.dart true true true false
The negation operator !
inverts a boolean value.
void main() { print(!true); print(!false); print(!(4 < 3)); }
This shows !
flipping true to false and evaluating an
expression to true.
$ dart main.dart false true true
Dart Comparison Operators
Comparison operators, also known as relational operators, compare values and return a boolean result, essential for decision-making in code.
Symbol | Meaning |
---|---|
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
== | Equal to |
!= | Not equal to |
The table above lists the comparison operators in Dart.
void main() { print(3 < 4); print(3 == 4); print(4 >= 3); print(4 != 3); }
This example compares integers using ==
for equality (unlike
some languages that use =
), yielding boolean results.
$ dart main.dart true false true true
Dart Bitwise Operators
Bitwise operators manipulate binary representations of numbers, performing bit-by-bit operations, useful for low-level tasks like flag management.
Symbol | Meaning |
---|---|
& | Bitwise AND |
| | Bitwise OR |
^ | Bitwise XOR |
~ | Bitwise NOT |
<< | Left shift |
>> | Right shift |
The bitwise AND (&
) yields 1 only when both corresponding bits
are 1.
00110 & 00011 = 00010
For 6 (00110) and 3 (00011), the result is 2 (00010).
void main() { print(6 & 3); }
$ dart main.dart 2
The bitwise OR (|
) yields 1 if either bit is 1.
00110 | 00011 = 00111
For 6 and 3, the result is 7 (00111).
void main() { print(6 | 3); }
$ dart main.dart 7
The bitwise XOR (^
) yields 1 if exactly one bit is 1.
00110 ^ 00011 = 00101
For 6 and 3, the result is 5 (00101).
void main() { print(6 ^ 3); }
$ dart main.dart 5
Dart Ternary Operator
The ternary operator ?:
provides a concise conditional
expression, evaluating one of two expressions based on a boolean condition.
condition ? expr1 : expr2
If the condition is true, expr1
is evaluated; otherwise,
expr2
is evaluated.
void main() { var age = 18; var isAdult = (age >= 18) ? true : false; if (isAdult) { print("he is adult"); } else { print("he is minor"); } }
This uses the ternary operator to set isAdult
based on age,
then prints a message using an if
statement.
$ dart main.dart he is adult
Dart Spread Operator
The spread operator ...
inserts all elements of a collection
into another, simplifying list, set, or map construction.
void main() { var vals = [1, 2, 3]; var vals2 = [...vals, 4, 5, 6]; print(vals); print(vals2); }
This expands vals
into vals2
, adding more
elements to create a new list.
$ dart main.dart [1, 2, 3] [1, 2, 3, 4, 5, 6]
Dart Cascade Operator
The cascade operator ..
allows multiple operations on the same
object, enhancing code fluency and readability.
class User { var fname; var lname; var occupation; String toString() { return "$fname $lname is a $occupation"; } } void main() { var u = User() ..fname = "John" ..lname = "Doe" ..occupation = "gardener"; print(u); }
This initializes a User
object's properties using cascades,
then prints its string representation.
$ dart main.dart John Doe is a gardener
Dart is & is! Operators
The is
and is!
operators check an object's type at
runtime, returning true if the type matches or does not match,
respectively.
class Base {} class Derived extends Base {} void main() { var b = Base(); var d = Derived(); print(d is Base); print(d is! Base); print(b is Derived); print(d is Object); print(d is! Object); }
This checks type relationships, showing inheritance and object type properties.
$ dart main.dart true false false true false
Dart Null-Aware Operators
Dart's null-aware operators, like ??
and ??=
,
handle null values safely, providing defaults or conditional assignments to
prevent null-related errors.
void main() { String? name; // Null-coalescing operator String displayName = name ?? "Guest"; print(displayName); // Null-aware assignment name ??= "Anonymous"; print(name); name ??= "User"; print(name); }
The ??
operator provides a default if name
is
null, while ??=
assigns a value only if the variable is null,
leaving it unchanged otherwise.
$ dart main.dart Guest Anonymous Anonymous
Dart Conditional Member Access Operator
The conditional member access operator ?.
safely accesses
properties or methods of an object, returning null if the object is null,
avoiding runtime errors.
void main() { String? text; // Conditional member access int? length = text?.length; print(length); text = "Hello"; length = text?.length; print(length); }
This safely accesses the length
property, returning null when
text
is null and the actual length when non-null.
$ dart main.dart null 5
Dart Type Cast Operator
The type cast operator as
converts an object to a specific type
at runtime, throwing an exception if the cast is invalid, useful for working
with dynamic or interface types.
void main() { var value = "Dart"; // Type cast String text = value as String; print(text.toUpperCase()); // Safe cast with is check if (value is String) { String safeText = value as String; print(safeText.length); } }
This casts value
to a String, allowing String-specific
operations, and demonstrates a safe cast with a type check.
$ dart main.dart DART 4
Dart Operator Precedence
Operator precedence determines the order in which operators are evaluated, resolving ambiguities in expressions to ensure consistent results.
void main() { print(3 + 5 * 6); print((3 + 5) * 6); print(!true || true); print(!(true || true)); }
Multiplication has higher precedence than addition, so 5 * 6
is evaluated first, yielding 33. Parentheses override this, yielding 48.
Negation precedes ||
, affecting logical outcomes.
$ dart main.dart 33 48 true false
Dart Operator Precedence Table
The following table lists the operator precedence in Dart, from highest to lowest. Operators with higher precedence are evaluated before those with lower precedence. Operators on the same row have equal precedence and are evaluated according to associativity rules.
Precedence | Operator(s) | Description |
---|---|---|
1 (highest) | [] , () , . , ?. | Member access, function call |
2 | ++ , -- , ~ | Postfix increment/decrement, bitwise NOT |
3 | ++ , -- , + , - , ! | Prefix increment/decrement, unary plus/minus, logical NOT |
4 | * , / , % , ~/ | Multiplicative |
5 | + , - | Additive |
6 | >> , << | Bitwise shift |
7 | > , < , >= , <= , is , is! | Relational, type test |
8 | == , != | Equality |
9 | & | Bitwise AND |
10 | ^ | Bitwise XOR |
11 | | | Bitwise OR |
12 | && | Logical AND |
13 | || | Logical OR |
14 | ?? | Null-coalescing |
15 | ? : | Conditional (ternary) |
16 | = , += , -= , *= , /= , %= , ~/= , &= , |= , ^= , <<= , >>= , ??= | Assignment |
17 (lowest) | , | Comma |
Refer to this table to understand how Dart evaluates complex expressions and to avoid unexpected results due to operator precedence.
Associativity Rule
Associativity determines the evaluation order for operators with equal
precedence. Most operators, like /
and *
, are
left-to-right, while assignment and unary operators are right-to-left.
void main() { print(9 / 3 * 3); var j = 0; j *= 3 + 1; print(j); }
The expression 9 / 3 * 3
evaluates left-to-right as
(9 / 3) * 3
, yielding 9. The compound assignment
*=
is right-to-left, so 3 + 1
is evaluated first,
then multiplied by j
.
$ dart main.dart 9.0 0
Source
Dart operators - language reference
This tutorial covered Dart operators, their roles in expressions, and how precedence and associativity shape evaluation.
Author
List all Dart tutorials.