DEV Community

Ge Ji
Ge Ji

Posted on

Dart Lesson 2: operators and flow control. They act like a program's "logic engine"

Today, we'll dive into the core that makes programs "come alive" - operators and flow control. They act like a program's "logic engine," driving it to run according to the rules we set.

I. Operators: The "Processors" of Data

Operators are used to manipulate data. Dart has a variety of operators, and we'll focus on the following categories:

1. Arithmetic Operators

These perform basic mathematical operations.

Operator Name Example Description
+ Addition 5 + 3 → 8 Adds two numbers
- Subtraction 5 - 3 → 2 Subtracts the second number from the first
* Multiplication 5 * 3 → 15 Multiplies two numbers
/ Division 5 / 3 → 1.666... Divides two numbers, returns a floating-point result
~/ Integer Division 5 ~/ 3 → 1 Divides two numbers, returns only the integer part (discards decimals)
% Modulus (Remainder) 5 % 3 → 2 Returns the remainder of division
++ Increment a++ 或 ++a Increases the variable by 1; a++ uses the value first, then increments; ++a increments first, then uses the value
-- Decrement a-- 或 --a Decreases the variable by 1; follows the same logic as increment

Example Code:

void main() {
  int a = 10;
  int b = 3;

  print(a + b); // Output: 13
  print(a - b); // Output: 7
  print(a * b); // Output: 30
  print(a / b); // Output: 3.3333333333333335
  print(a ~/ b); // Output: 3
  print(a % b); // Output: 1

  int c = 5;
  print(c++); // Output: 5 (uses c first, then increments)
  print(c); // Output: 6
  print(++c); // Output: 7 (increments first, then uses c)
}
Enter fullscreen mode Exit fullscreen mode

2. Relational Operators

These compare relationships between two values and return a boolean (true or false).

Operator Name Example
== Equal to 5 == 3 → false
!= Not equal to 5 != 3 → true
> Greater than 5 > 3 → true
< Less than 5 < 3 → false
>= Greater than or equal to 5 >= 5 → true
<= Less than or equal to 3 <= 2 → false

Example Code:

void main() {
  int x = 7;
  int y = 7;

  print(x == y); // Output: true
  print(x != y); // Output: false
  print(x > y); // Output: false
  print(x <= y); // Output: true
}
Enter fullscreen mode Exit fullscreen mode

3. Logical Operators

These combine multiple boolean expressions to perform logical checks.

Operator Name Description Example (if a=true, b=false)
&& Logical AND Returns true only if both sides are true a && b → false
|| Logical OR Returns true if at least one side is true a||b → true
! Logical NOT Inverts the boolean value (true becomes false, and vice versa) !a → false

Example Code:

void main() {
  bool isSunny = true;
  bool isWarm = false;

  // Logical AND: Is it sunny AND warm?
  print(isSunny && isWarm); // Output: false

  // Logical OR: Is it sunny OR warm?
  print(isSunny || isWarm); // Output: true

  // Logical NOT: Is it NOT sunny?
  print(!isSunny); // Output: false

  // Combined use: Check if a number is between 1 and 10 (inclusive)
  int num = 5;
  bool isBetween = num >= 1 && num <= 10;
  print(isBetween); // Output: true
}
Enter fullscreen mode Exit fullscreen mode

4. Key Focus: ?? Null Coalescing Operator (Introduction)

In Dart, we can declare nullable variables (by adding ?). The ?? operator handles potentially null values: it returns the left value if it’s not null; otherwise, it returns the right value.

Example Code:

void main() {
  String? name; // Nullable string, initial value is null
  String displayName = name ?? "Guest"; // name is null, so use "Guest"
  print(displayName); // Output: Guest

  name = "Alice";
  displayName = name ?? "Guest"; // name is not null, so use "Alice"
  print(displayName); // Output: Alice
}
Enter fullscreen mode Exit fullscreen mode

This operator is extremely useful in practice. It concisely sets default values for nullable variables, avoiding errors caused by null.

II. Branching Structures: The "Crossroads" of Programs

Branching structures let programs execute different code blocks based on conditions.

1. if-else Statements

The most common branching structure, with the following syntax:

if (condition) {
  // Code to run if condition is true
} else if (anotherCondition) {
  // Code to run if the first condition is false and this one is true
} else {
  // Code to run if all conditions are false
}
Enter fullscreen mode Exit fullscreen mode

else if and else are optional.

Example 1: Simple if-else

void main() {
  int score = 85;

  if (score >= 60) {
    print("Exam passed!");
  } else {
    print("Exam failed. Keep trying!");
  }
  // Output: Exam passed!
}
Enter fullscreen mode Exit fullscreen mode

Example 2: Multi-branch if-else if-else

void main() {
  int grade = 75;

  if (grade >= 90) {
    print("Excellent");
  } else if (grade >= 80) {
    print("Good");
  } else if (grade >= 60) {
    print("Pass");
  } else {
    print("Fail");
  }
  // Output: Pass
}
Enter fullscreen mode Exit fullscreen mode

2. switch-case Statements

switch-case is useful when comparing a variable to multiple constant values. Syntax:

switch (expression) {
  case constant1:
    // Code to run if expression equals constant1
  break;  // Exit the switch statement
  case constant2:
    // Code to run if expression equals constant2
  break;
  // ... more cases
  default:
    // Code to run if expression doesn't match any case (optional)
}
Enter fullscreen mode Exit fullscreen mode
  • case must be followed by a constant.
  • break prevents code from "falling through" to the next case. To intentionally fall through, use continue with a label.
  • default acts like else.

Example Code:

void main() {
  String day = "Monday";

  switch (day) {
    case "Monday":
      print("Monday: Start of a new week!");
      break;
    case "Friday":
      print("Friday: Weekend is near!");
      break;
    case "Saturday":
    case "Sunday": // Multiple cases can share code
      print("Weekend: Take a break!");
      break;
    default:
      print("Weekday: Keep up the good work!");
  }
  // Output: Monday: Start of a new week!
}
Enter fullscreen mode Exit fullscreen mode

III. Looping Structures: The "Repeaters" of Programs

Loops repeat code execution until a specific condition is met.

1. for Loops

Versatile and widely used, with the following syntax:

for (initialization; condition; update) {
  // Loop body: runs if condition is true
}
Enter fullscreen mode Exit fullscreen mode
  • Initialization: Runs once before the loop starts (often initializes a loop variable).
  • Condition: Checked before each iteration; loop runs if true, exits if false.
  • Update: Runs after each loop body (often updates the loop variable).

Example 1: Basic for Loop (Print 0 to 4)

void main() {
  for (int i = 0; i < 5; i++) {
    print(i);
  }
  // Output: 0, 1, 2, 3, 4 (one per line)
}
Enter fullscreen mode Exit fullscreen mode

Example 2: Iterating Over Lists (for-in Loop)
Dart offers a simpler for-in loop to iterate over iterable objects (e.g., lists):

void main() {
  List<String> fruits = ["Apple", "Banana", "Orange"];

  for (String fruit in fruits) {
    print(fruit);
  }
  // Output: Apple, Banana, Orange (one per line)
}
Enter fullscreen mode Exit fullscreen mode

2. while and do-while Loops

  • while loop: Checks the condition first; runs the body only if true.
while (condition) {
  // Loop body
}
Enter fullscreen mode Exit fullscreen mode
  • do-while loop: Runs the body once first, then checks the condition; repeats if true (runs at least once).
do {
  // Loop body
} while (condition);
Enter fullscreen mode Exit fullscreen mode

Example 1: while Loop (Sum of 1 to 10)

void main() {
  int sum = 0;
  int i = 1;

  while (i <= 10) {
    sum += i; // Equivalent to sum = sum + i
    i++;
  }

  print("Sum of 1 to 10: $sum"); // Output: Sum of 1 to 10: 55
}
Enter fullscreen mode Exit fullscreen mode

Example 2: do-while Loop (Simple Input Validation)

import 'dart:io'; // For reading console input

void main() {
  int age;
  do {
    print("Enter your age (must be greater than 0):");
    String? input = stdin.readLineSync(); // Read input
    age = int.tryParse(input ?? "") ?? 0; // Convert to int; 0 if failed
  } while (age <= 0);

  print("Your age is: $age");
}
Enter fullscreen mode Exit fullscreen mode

This code keeps prompting the user until a valid age (> 0) is entered.

3. break and continue Statements

  • break: Immediately exits the current loop (terminates it).
  • continue: Skips the remaining code in the current iteration and moves to the next one.

Example 1: Using break (Stop When Target is Found)

void main() {
  List<int> numbers = [3, 7, 12, 5, 9];
  int target = 12;
  bool found = false;

  for (int num in numbers) {
    if (num == target) {
      found = true;
      break; // Exit loop once target is found
    }
  }

  print(found ? "Target found!" : "Target not found!"); // Output: Target found!
}
Enter fullscreen mode Exit fullscreen mode

Example 2: Using continue (Skip Even Numbers)

void main() {
  for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
      // If even
      continue; // Skip to next iteration
    }
    print(i); // Print only odd numbers
  }
  // Output: 1, 3, 5, 7, 9 (one per line)
}
Enter fullscreen mode Exit fullscreen mode

IV. Bonus: Operator Precedence

When an expression has multiple operators, their execution order is determined by precedence. For example, multiplication and division have higher precedence than addition and subtraction. If unsure, use parentheses () to override precedence — expressions inside parentheses run first.

Example:

void main() {
  print(
    2 + 3 * 4,
  ); // Multiplication first: 3*4=12, then addition: 2+12=14 → Output: 14
  print(
    (2 + 3) * 4,
  ); // Parentheses first: 2+3=5, then multiplication: 5*4=20 → Output: 20
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)