Skip to content

Operators

Operators are special symbols that perform operations on operands. Dart supports a rich set of operators for various operations.

Arithmetic Operators

dart
int a = 10, b = 3;

print(a + b);   // 13 - Addition
print(a - b);   // 7  - Subtraction
print(a * b);   // 30 - Multiplication
print(a / b);   // 3.333... - Division (returns double)
print(a ~/ b);  // 3  - Integer division
print(a % b);   // 1  - Modulo (remainder)

// Unary operators
print(-a);      // -10 - Negation

Increment and Decrement

dart
int x = 5;

print(++x);  // 6 - Pre-increment (increment then return)
print(x++);  // 6 - Post-increment (return then increment)
print(x);    // 7

print(--x);  // 6 - Pre-decrement
print(x--);  // 6 - Post-decrement
print(x);    // 5

Equality and Relational Operators

dart
int a = 10, b = 20;

print(a == b);   // false - Equal to
print(a != b);   // true  - Not equal to
print(a > b);    // false - Greater than
print(a < b);    // true  - Less than
print(a >= b);   // false - Greater than or equal to
print(a <= b);   // true  - Less than or equal to

Logical Operators

dart
bool a = true, b = false;

print(a && b);   // false - AND
print(a || b);   // true  - OR
print(!a);       // false - NOT

Assignment Operators

dart
int a = 10;

a += 5;   // a = a + 5  (15)
a -= 3;   // a = a - 3  (12)
a *= 2;   // a = a * 2  (24)
a ~/= 4;  // a = a ~/ 4 (6)
a %= 4;   // a = a % 4  (2)

Type Test Operators

dart
var value = 'Hello';

print(value is String);      // true
print(value is! int);        // true
print(value is Object);      // true

// Type cast
dynamic obj = 'Hello';
String str = obj as String;  // Cast to String

Bitwise Operators

dart
int a = 5;   // 0101 in binary
int b = 3;   // 0011 in binary

print(a & b);   // 1  (0001) - AND
print(a | b);   // 7  (0111) - OR
print(a ^ b);   // 6  (0110) - XOR
print(~a);      // -6 - NOT (inverts bits)
print(a << 1);  // 10 (1010) - Left shift
print(a >> 1);  // 2  (0010) - Right shift

Conditional Expressions

Ternary Operator

dart
int age = 18;
String status = age >= 18 ? 'Adult' : 'Minor';
print(status);  // Adult

Null-coalescing Operator

dart
String? name;
String displayName = name ?? 'Guest';
print(displayName);  // Guest

// Assign if null
name ??= 'Default';
print(name);  // Default

Cascade Notation

Allows you to perform a sequence of operations on the same object:

dart
class Person {
  String? name;
  int? age;
  
  void introduce() {
    print('I am $name, $age years old');
  }
}

void main() {
  Person person = Person()
    ..name = 'Alice'
    ..age = 25
    ..introduce();  // I am Alice, 25 years old
  
  // Null-aware cascade
  Person? nullablePerson;
  nullablePerson?..name = 'Bob'..age = 30;
}

Spread Operator

dart
List<int> list1 = [1, 2, 3];
List<int> list2 = [4, 5, 6];

// Spread operator
List<int> combined = [...list1, ...list2];
print(combined);  // [1, 2, 3, 4, 5, 6]

// Null-aware spread
List<int>? nullableList;
List<int> safe = [...?nullableList, 7, 8];
print(safe);  // [7, 8]

Null-aware Operators

Null-aware Access

dart
class Person {
  String? name;
}

Person? person;

// Safe navigation
print(person?.name);  // null (no error)

// Chaining
print(person?.name?.length);  // null

Null-aware Assignment

dart
String? name;
name ??= 'Default';  // Assign only if null
print(name);  // Default

name ??= 'Another';  // Won't assign (name is not null)
print(name);  // Default

Null Assertion

dart
String? nullable = 'Hello';
String nonNull = nullable!;  // Assert non-null
print(nonNull);  // Hello

// Throws error if null
String? nullValue;
// String error = nullValue!;  // Error: Null check operator used on a null value

Index Operator

dart
List<int> numbers = [10, 20, 30, 40];
print(numbers[0]);  // 10
print(numbers[2]);  // 30

Map<String, int> ages = {'Alice': 25, 'Bob': 30};
print(ages['Alice']);  // 25

Operator Precedence

From highest to lowest:

  1. Postfix: expr++, expr--, (), [], ., ?.
  2. Unary prefix: -expr, !expr, ~expr, ++expr, --expr
  3. Multiplicative: *, /, %, ~/
  4. Additive: +, -
  5. Shift: <<, >>
  6. Bitwise AND: &
  7. Bitwise XOR: ^
  8. Bitwise OR: |
  9. Relational: >=, >, <=, <, as, is, is!
  10. Equality: ==, !=
  11. Logical AND: &&
  12. Logical OR: ||
  13. Null-aware: ??
  14. Conditional: expr1 ? expr2 : expr3
  15. Cascade: .., ?..
  16. Assignment: =, *=, /=, +=, -=, etc.

Operator Overloading

You can override operators in custom classes:

dart
class Vector {
  final double x, y;
  
  Vector(this.x, this.y);
  
  // Overload + operator
  Vector operator +(Vector other) {
    return Vector(x + other.x, y + other.y);
  }
  
  // Overload - operator
  Vector operator -(Vector other) {
    return Vector(x - other.x, y - other.y);
  }
  
  // Overload * operator (scalar multiplication)
  Vector operator *(double scalar) {
    return Vector(x * scalar, y * scalar);
  }
  
  @override
  String toString() => 'Vector($x, $y)';
}

void main() {
  Vector v1 = Vector(3, 4);
  Vector v2 = Vector(1, 2);
  
  print(v1 + v2);  // Vector(4.0, 6.0)
  print(v1 - v2);  // Vector(2.0, 2.0)
  print(v1 * 2);   // Vector(6.0, 8.0)
}

Best Practices

  1. Use parentheses to make complex expressions clearer
  2. Prefer ?? over explicit null checks when providing defaults
  3. Use cascade notation for multiple operations on the same object
  4. Be careful with ! - only use when you're certain the value isn't null
  5. Use ?. for safe navigation through potentially null objects

Complete Example

dart
class Calculator {
  double? lastResult;
  
  double calculate(double a, double b, String operator) {
    lastResult = switch (operator) {
      '+' => a + b,
      '-' => a - b,
      '*' => a * b,
      '/' => b != 0 ? a / b : 0,
      _ => 0,
    };
    return lastResult!;
  }
  
  void reset() => lastResult = null;
}

void main() {
  Calculator calc = Calculator()
    ..calculate(10, 5, '+')
    ..calculate(20, 4, '*');
  
  print('Last result: ${calc.lastResult}');  // 80.0
  
  // Null-aware operations
  String? input;
  String display = input ?? 'No input';
  print(display);  // No input
  
  // Conditional expression
  int age = 25;
  String category = age >= 18 ? 'Adult' : 'Minor';
  print('Category: $category');  // Adult
  
  // Spread operator
  List<int> numbers1 = [1, 2, 3];
  List<int> numbers2 = [4, 5, 6];
  List<int> all = [...numbers1, ...numbers2];
  print('All numbers: $all');  // [1, 2, 3, 4, 5, 6]
}

Next Steps

Content is for learning and research only.