Control Flow in Dart
Learn conditionals, loops, switch statements, and pattern matching in Dart with practical Docker-ready examples
Control flow is how a program decides what to do and how many times to do it. Dart gives you a familiar C-style toolkit — if/else, for, while, switch — but layers modern features on top: arrow-style conditional expressions, collection-if and collection-for inside literals, and the powerful pattern-matching switch expressions introduced in Dart 3.
As a multi-paradigm language, Dart lets you write straightforward imperative loops and expression-oriented code that reads more like a functional language. A switch can be a statement that runs side effects, or an expression that produces a value. The same applies to conditionals: there’s the classic ternary ?: and the null-aware ?? operator for the very common “use this, or a default” case.
In this tutorial you’ll learn how to branch with if/else, choose among many cases with switch, iterate with for and while, control loops with break and continue, and use Dart’s expression-based conditionals to write concise, readable code.
Conditionals: if, else, and ternary
The if statement evaluates a boolean condition. Unlike some languages, Dart requires the condition to be an actual bool — there’s no “truthy” coercion of integers or strings.
Create a file named conditionals.dart:
| |
Two expression forms worth remembering:
- Ternary
?:— picks between two values based on a condition. - Null-coalescing
??— returns its left operand unless it’snull, in which case it returns the right. This pairs naturally with Dart’s sound null safety.
Switch statements and expressions
Dart’s switch comes in two flavors. As a statement it runs code for the matching case. Dart never implicitly falls through from one non-empty case to the next, but it doesn’t auto-break either: a non-empty case must explicitly end with break (or return/continue/throw) unless it’s the final clause — omitting it is a compile error. As an expression (Dart 3+) it evaluates to a value, using => for each case and a _ wildcard for the default.
Create a file named switch_demo.dart:
| |
Notice the || logical-or pattern (10 || 9) that matches multiple values in a single case, and the _ wildcard that handles everything else. The ~/ operator is integer division, so 85 ~/ 10 is 8.
For loops and while loops
Dart supports the standard counting for loop, the for-in loop for iterating over collections, and while / do-while loops.
Create a file named loops.dart:
| |
The for-in loop is the idiomatic way to walk a collection. Lists also offer a functional forEach method, but for-in integrates cleanly with break and continue.
Loop control: break and continue
break exits the nearest enclosing loop immediately; continue skips to the next iteration. Labels let you target an outer loop from within a nested one.
Create a file named loop_control.dart:
| |
Control flow inside collections
A feature unique to Dart’s expressiveness: you can use if and for inside list, set, and map literals. This is called collection-if and collection-for, and it lets you build collections declaratively without a separate loop.
Create a file named collection_flow.dart:
| |
The resulting list is built in one expression: the if conditionally adds 'bonus', and the for expands into three generated entries.
Running with Docker
| |
Expected Output
Running conditionals.dart:
It is mild
Today is comfortable
Hello, guest
Running switch_demo.dart:
Weekend
Grade: B
Running loops.dart:
Count: 1
Count: 2
Count: 3
Fruit: apple
Fruit: banana
Fruit: cherry
T-minus 3
T-minus 2
T-minus 1
Runs once even though n is 0
Running loop_control.dart:
Odd: 1
Odd: 3
Odd: 5
Checked Ada
Found Linus, stopping
Breaking outer at row=1 col=2
Running collection_flow.dart:
[base, bonus, item1, item2, item3]
Total items: 5
Key Concepts
- Conditions must be
bool— Dart has no truthy/falsy coercion, soif (0)is a compile error; you must write an explicit comparison. - Switch doesn’t fall through — non-empty cases must end with an explicit
break(orreturn/continue/throw) unless they’re the last clause, while empty stacked cases (likecase 'SAT': case 'SUN':) share the next case’s body. - Switch expressions return values — use
switch (x) { pattern => value, _ => default }with=>and a_wildcard for concise, value-producing branching (Dart 3+). - Multiple loop styles — counting
for,for-infor collections,while, anddo-while(which always runs once) cover every iteration need. breakandcontinue— exit or skip iterations; labeled breaks let you escape an outer loop from inside nested loops.- Collection-
ifand collection-for— embed control flow directly inside list, set, and map literals to build collections declaratively. - Null-aware
??— a clean way to express “use this value, or fall back to a default” that complementsif-based null checks.
Comments
Loading comments...
Leave a Comment