Dart: Dart Operators

Last updated: 2026-08-26

Operators are the verbs of code — master them to make data "move."

1. What You Will Learn


2. A Developer's Real Story

(1) Pain Point: NullPointerException Crashing Batch Tasks

Bob's DataPipeline frequently crashed while processing millions of orders because some orders lacked optional fields. The code was littered with if (value != null) checks, but one was missed, causing the processing of 300,000 orders to halt and requiring a complete re-run.

(2) The Null Safety Operator Solution

Dart provides three operators — ?. (safe access), ?? (null coalescing), and ??= (null-aware assignment) — that make null handling concise and safe.

DART
// Before: verbose null checking
String getCity(Order order) {
  if (order.customer != null) {
    if (order.customer!.address != null) {
      return order.customer!.address!.city;
    }
  }
  return 'Unknown';
}

// After: null-safe operators
String getCity(Order order) =>
    order.customer?.address?.city ?? 'Unknown';
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

(3) Benefits


3. Arithmetic and Relational Operators

(1) Arithmetic Operators

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Basic Arithmetic

DART
void main() {
  int a = 17;
  int b = 5;

  print(a + b);   // 22 - Addition
  print(a - b);   // 12 - Subtraction
  print(a * b);   // 85 - Multiplication
  print(a / b);   // 3.4 - Division (returns double)
  print(a ~/ b);  // 3 - Integer division
  print(a % b);   // 2 - Modulo (remainder)

  // Prefix and postfix increment
  int count = 10;
  print(count++); // 10 (returns then increments)
  print(count);   // 11
  print(++count); // 12 (increments then returns)
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.
Operator Meaning Example Result
+ Addition 17 + 5 22
- Subtraction 17 - 5 12
* Multiplication 17 * 5 85
/ Division (returns double) 17 / 5 3.4
~/ Integer Division 17 ~/ 5 3
% Modulo (Remainder) 17 % 5 2

(2) Relational Operators

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Comparison Operations

DART
void main() {
  int orders = 1500;
  int threshold = 1000;

  print(orders > threshold);     // true
  print(orders < threshold);     // false
  print(orders >= 1500);         // true
  print(orders <= 1500);         // true
  print(orders == 1500);         // true
  print(orders != 1000);         // true

  // String comparison is lexicographic
  print('apple' < 'banana');     // true
  print('USD' == 'USD');         // true
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

4. Logical and Bitwise Operators

(1) Logical Operators

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Logical Operations

DART
void main() {
  bool isProduction = true;
  bool hasErrors = false;

  print(isProduction && !hasErrors);  // true - AND + NOT
  print(isProduction || hasErrors);   // true - OR
  print(!isProduction);               // false - NOT

  // Short-circuit evaluation
  String? name = null;
  // name.length > 0 would crash, but:
  print(name != null && name.isNotEmpty);  // false (safe)
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.
Operator Meaning Short-Circuit
&& Logical AND Left false -> right not evaluated
` `
! Logical NOT

(2) Bitwise Operators

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Bitwise Operations

DART
void main() {
  int flags = 0b1010;  // 10 in binary
  int mask = 0b1100;   // 12 in binary

  print(flags & mask);   // 8  (0b1000) - AND
  print(flags | mask);   // 14 (0b1110) - OR
  print(flags ^ mask);   // 6  (0b0110) - XOR
  print(~flags);         // -11 (inverted bits) - NOT
  print(flags << 2);     // 40 (0b101000) - Left shift
  print(flags >> 1);     // 5  (0b0101) - Right shift
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

5. Assignment and Compound Assignment Operators

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Compound Assignment

DART
void main() {
  int total = 0;
  double revenue = 0.0;

  total += 100;          // total = total + 100 = 100
  total -= 30;           // total = 70
  total *= 2;            // total = 140
  total ~/= 3;           // total = 46 (integer division)
  revenue += 52500.75;   // revenue = 52500.75

  // Null-aware assignment
  String? outputPath;
  outputPath ??= '/tmp/output';  // Assign if null
  print(outputPath);             // /tmp/output
  outputPath ??= '/other/path';  // Not assigned (already non-null)
  print(outputPath);             // /tmp/output
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.
Operator Equivalent To Example
+= a = a + b total += 100
-= a = a - b total -= 30
*= a = a * b total *= 2
~/= a = a ~/ b total ~/= 3
??= a = a ?? b path ??= '/default'

6. Cascade Operator .. and ?..

(1) Cascade Operator

The cascade operator .. allows performing multiple operations on the same object without repeatedly referencing the variable name.

100%
graph TD
  A[Operator System] --> B[Arithmetic + Relational + Logical]
  A --> C[Cascade ..]
  A --> D[Null Safety ?. ?? ??=]
  A --> E[Type Test is/as]
  C --> C1["object..method1()..method2()"]
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Cascade Operator

DART
class DataPipeline {
  String name = '';
  int batchSize = 0;
  bool verbose = false;
  final List<String> sources = [];

  void start() => print('$name started');
}

void main() {
  // Without cascade - repetitive
  final pipeline1 = DataPipeline();
  pipeline1.name = 'Analytics';
  pipeline1.batchSize = 50000;
  pipeline1.verbose = true;
  pipeline1.sources.add('orders.csv');
  pipeline1.start();

  // With cascade - fluent and clean
  final pipeline2 = DataPipeline()
    ..name = 'Analytics'
    ..batchSize = 50000
    ..verbose = true
    ..sources.add('orders.csv')
    ..start();
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Null-Safe Cascade ?..

DART
class Customer {
  String? name;
  String? email;
}

void main() {
  Customer? customer;

  // Null-safe cascade - skipped if object is null
  customer?..name = 'Bob'..email = 'bob@example.com';
  print(customer);  // null (cascade was skipped)

  customer = Customer();
  customer?..name = 'Bob'..email = 'bob@example.com';
  print(customer?.name);  // Bob
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.
Operator Meaning When Object is null
.. Cascade operation Error
?.. Null-safe cascade Skips entire cascade

7. Null Safety Operators

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: Three Null Safety Operators

DART
class Address {
  final String city;
  Address(this.city);
}

class Customer {
  final String name;
  final Address? address;
  Customer(this.name, {this.address});
}

class Order {
  final String id;
  final Customer? customer;
  Order(this.id, {this.customer});
}

void main() {
  // ?. - null-safe access
  Order order = Order('ORD-001');
  print(order.customer?.name);          // null (safe)
  // print(order.customer.name);        // Runtime error!

  // ?? - null coalescing
  String city = order.customer?.address?.city ?? 'Unknown';
  print(city);                          // Unknown

  // ??= - null-aware assignment
  String? outputPath;
  outputPath ??= '/tmp/reports';
  print(outputPath);                    // /tmp/reports
  outputPath ??= '/other/path';
  print(outputPath);                    // /tmp/reports (unchanged)
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.
Operator Meaning Example Result
?. Safe access obj?.method() null or call result
?? Null coalescing value ?? default value if non-null, else default
??= Null-aware assignment var ??= value Assigns if null

8. Type Test Operators

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

: is / is! / as

DART
void main() {
  Object value = '1,500.00 USD';

  // is - type check (returns bool)
  if (value is String) {
    print('String length: ${value.length}');  // Type promoted!
  }

  // is! - negative type check
  if (value is! int) {
    print('Not an integer');
  }

  // as - type cast (throws if wrong)
  String text = value as String;       // OK
  // int number = value as int;        // Runtime error!

  // Safe cast pattern
  if (value is String) {
    String safe = value;               // No cast needed (promoted)
    print(safe.toUpperCase());
  }
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.
Operator Meaning On Failure
is Type check Returns false
is! Negated type check Returns true
as Type cast Throws TypeError

9. Full Example: DataPipeline Order Processing with Operators

DART
// ============================================
// DataPipeline Order Processing with Operators
// Demonstrates all operator categories
// ============================================

class Order {
  final String id;
  final double amount;
  String? discountCode;
  double? discountPercent;

  Order({required this.id, required this.amount});

  // Null-safe operators for discount calculation
  double get discountedAmount =>
      amount - (amount * (discountPercent ?? 0));

  double get tax => discountedAmount * 0.08;

  double get total => discountedAmount + tax;

  String formatUSD() => '\$${total.toStringAsFixed(2)} USD';
}

class Report {
  final List<Order> orders = [];
  var totalRevenue = 0.0;
  var orderCount = 0;

  void addOrder(Order order) {
    orders.add(order);
    totalRevenue += order.total;       // Compound assignment
    orderCount++;
  }

  double get averageOrderValue =>
      orderCount > 0 ? totalRevenue / orderCount : 0;

  bool get isHighVolume => orderCount >= 1000;

  String get statusLabel => isHighVolume ? 'High Volume' : 'Normal';
}

void main() {
  final report = Report()
    ..addOrder(Order(id: 'ORD-001', amount: 1500.0)
      ..discountPercent = 0.1)
    ..addOrder(Order(id: 'ORD-002', amount: 3250.50)
      ..discountCode = 'SAVE20'
      ..discountPercent = 0.2)
    ..addOrder(Order(id: 'ORD-003', amount: 890.25));

  print('=== DataPipeline Order Report ===');
  for (final order in report.orders) {
    final discount = order.discountPercent != null
        ? '${(order.discountPercent! * 100).toInt()}%'
        : 'None';
    print('  ${order.id}: ${order.formatUSD()} (Discount: $discount)');
  }

  print('\n--- Summary ---');
  print('Orders:     ${report.orderCount}');
  print('Revenue:    \$${report.totalRevenue.toStringAsFixed(2)} USD');
  print('Average:    \$${report.averageOrderValue.toStringAsFixed(2)} USD');
  print('Status:     ${report.statusLabel}');

  // Type test
  print('\nType check: report is ${report.runtimeType}');
  print('Is Report: ${report is Report}');
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or `dart run`. All Dart course examples are based on Dart 3.x / Flutter 3.x; results may vary slightly with SDK version.

Output:

TEXT 📖 Display only
=== DataPipeline Order Report ===
  ORD-001: $1458.00 USD (Discount: 10%)
  ORD-002: $2807.43 USD (Discount: 20%)
  ORD-003: $961.47 USD (Discount: None)

--- Summary ---
Orders:     3
Revenue:    $5226.90 USD
Average:    $1742.30 USD
Status:     Normal

Type check: report is Report
Is Report: true

❓ FAQ

Q: What's the difference between / and ~/? A: / always returns a double (e.g., 17 / 5 = 3.4), while ~/ returns the integer division result (e.g., 17 ~/ 5 = 3). Use ~/ when you need an integer result.

Q: What is the return value of the cascade operator ..? A: .. returns the object itself (not the return value of the last method), allowing continued chaining. This is a key difference from a regular method call.

Q: What's the difference between ??= and ??? A: ?? is the null coalescing operator, which returns the non-null value. ??= is the null-aware assignment operator, which only assigns if the variable is null and returns the result. x ??= y is equivalent to x = x ?? y.

Q: When should I use as instead of is? A: Prefer is for type checking, as the compiler performs automatic type promotion. Only use as when you are sure of the type or need an explicit cast, as an incorrect cast will throw an exception.

Q: When to use ?.. vs ..? A: Use ?.. when the object might be null, and .. when you are sure it is non-null. ?.. skips the entire cascade if the object is null.

Q: Does == compare references or values? A: Dart's == defaults to reference comparison (same as Java), but many built-in types (String, int, double) override == to compare values. Custom classes need to override both == and hashCode.

Q: Are bitwise operators commonly used in practice? A: Not frequently, but they are essential in scenarios like permission systems (flags), network protocol parsing, and encryption algorithms. Daily development mainly uses arithmetic and logical operators.


📖 Summary


📝 Exercises

  1. Basic (Difficulty ⭐): Write code using arithmetic operators to calculate the average amount per order for 1,500,000 orders with a total of 75,000,000 USD. Use the correct division operator.
  2. Intermediate (Difficulty ⭐⭐): Use the cascade operator .. to create and configure an object, setting at least 4 properties and calling 2 methods. Then compare it to the version without using cascade.
  3. Challenge (Difficulty ⭐⭐⭐): Implement a SafeValue<T> class using the ?., ??, and ??= operators to provide safe value access, default values, and lazy assignment, ensuring no null pointer exceptions are thrown during any operation.

← Previous Lesson | Next Lesson →

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏