Dart control flow
last modified October 18, 2026
In this article we talk about the flow control in Dart. We define several keywords that enable us to control the flow of a Dart program.
When a Dart program is run, the code is executed from top to bottom. The flow of
the program can be altered with various keywords, including if /
else, for, while, and
switch.
The control flow structures can be used to execute code conditionally or multiple times.
Dart if & else
The if statement specifies the conditional execution
of a block. If the expression evaluates to true, the block is executed.
If the else statement is present and the if
expression evaluates to false, the block following else is
executed. The condition must be a bool; Dart has no implicit
conversion of numbers or strings to booleans.
There can be multiple if/else statements.
Dart if/else examples
The following examples demonstrate conditional execution of blocks with
if/else.
void main() {
final value = 4;
if (value > 0) {
print('The number is positive');
}
}
In the example we have a simple condition; if the value variable
is positive, the message "The number is positive" is printed to the console.
Otherwise, nothing is printed. The message is printed since value 4 is
positive.
$ dart main.dart The number is positive
void main() {
final value = -4;
if (value > 0) {
print('The number is positive');
} else {
print('The number is negative');
}
}
Now we have added the second branch. The else statement specifies
the block that is executed if the if condition fails. For the
value -4, the message "The number is negative" is printed.
$ dart main.dart The number is negative
import 'dart:math';
void main() {
const max = 10;
final value = Random().nextInt(max) - 5;
print('value: $value');
if (value > 0) {
print('The number is positive');
} else if (value == 0) {
print('The number is zero');
} else {
print('The number is negative');
}
}
In this example, we add an additional branch with else if. We
generate random integers from -5 to 4. With the help of the if
and else statements we print a message for all three options.
Because the number is random, the output differs from run to run.
$ dart main.dart value: -3 The number is negative
Dart ternary and null-aware operators
For simple choices between two values, we can use the conditional
(?:) operator. The ?? operator chooses the right
operand when the left one is null.
void main() {
final age = 20;
final String? name = null;
final status = age >= 18 ? 'adult' : 'minor';
print(status);
print(name ?? 'anonymous');
}
The conditional expression yields a value, so it can be used where an
if statement cannot, for instance in an initializer.
$ dart main.dart adult anonymous
Dart if-case
Since Dart 3, an if statement can contain a case
clause with a pattern. The block is executed when the value matches the
pattern, and the pattern can bind variables.
void main() {
final data = {'name': 'John Doe', 'age': 34};
if (data case {'name': String name, 'age': int age}) {
print('$name is $age years old');
}
final pair = [1, 2];
if (pair case [int a, int b]) {
print('sum: ${a + b}');
}
}
The first pattern is a map pattern; it matches only if the map has a
name string and an age integer. The second is a list
pattern that matches a list of exactly two integers. The variables
name, age, a, and b are
available inside the corresponding blocks.
$ dart main.dart John Doe is 34 years old sum: 3
Dart switch statement
The switch statement is a selection control flow statement. It creates multiple
branches in a simpler way than using the combination of if /
else statements.
The switch keyword is used to test a value from the variable or the
expression against a group of values. The values are presented with the
case keyword. If the values match, the statement following the case
is executed. There is an optional default clause. It is executed if
no other match is found.
In Dart 3 and later, a non-empty case body does not fall through to
the next case, so the break statement is optional.
An empty case still falls through, which allows us to group
several values.
void main() {
final dayOfWeek = DateTime.now().weekday;
switch (dayOfWeek) {
case DateTime.sunday:
print('dies Solis');
case DateTime.monday:
print('dies Lunae');
case DateTime.tuesday:
print('dies Martis');
case DateTime.wednesday:
print('dies Mercurii');
case DateTime.thursday:
print('dies Jovis');
case DateTime.friday:
print('dies Veneris');
case DateTime.saturday:
print('dies Saturni');
}
}
The example determines the current day of the week and prints its Latin equivalent.
switch (dayOfWeek) {
...
}
In the round brackets, the switch keyword takes a value from an
expression, which is going to be tested. The body of the statement is placed
inside a pair of curly brackets. In the body, we can place multiple
case options.
case DateTime.sunday:
print('dies Solis');
With the case clause, we test the value of the matching
expression. If it is equal to DateTime.sunday, we print the Latin
dies Solis.
$ dart main.dart dies Solis
Empty cases can be grouped, and a case can match several values with the
logical-or pattern ||. The default clause handles
all the remaining values.
void main() {
final day = DateTime.saturday;
switch (day) {
case DateTime.saturday:
case DateTime.sunday:
print('weekend');
case DateTime.monday || DateTime.friday:
print('start or end of the work week');
default:
print('weekday');
}
}
Saturday and Sunday are grouped by two consecutive cases; Monday and Friday
share one case via the || pattern.
$ dart main.dart weekend
Dart switch expression
A switch expression produces a value. Its cases use the =>
arrow and are separated by commas. The compiler checks that all possible values
are covered, so for an enum or sealed class no default is needed.
enum Level { low, medium, high }
String describe(Level level) => switch (level) {
Level.low => 'Low priority',
Level.medium => 'Medium priority',
Level.high => 'High priority',
};
String size(int n) => switch (n) {
< 0 => 'negative',
0 => 'zero',
> 0 && < 10 => 'small',
_ => 'large',
};
void main() {
print(describe(Level.medium));
for (final n in [-3, 0, 5, 50]) {
print('$n is ${size(n)}');
}
}
The describe function covers every enum value, so the switch is
exhaustive. In size, we use relational and logical patterns;
the underscore _ matches anything else.
$ dart main.dart Medium priority -3 is negative 0 is zero 5 is small 50 is large
Dart while loop
The while statement is a control flow statement that allows code to
be executed repeatedly based on a given boolean condition.
This is the general form of the while loop:
while (expression) {
statement;
}
The while keyword executes the statements inside the block enclosed
by the curly brackets. The statements are executed each time the expression is
evaluated to true.
void main() {
var i = 0;
var sum = 0;
while (i < 10) {
i++;
sum += i;
}
print(sum);
}
In the code example, we calculate the sum of the values from 1 to 10. The
while loop has three parts: initialization, testing, and updating.
Each execution of the statement is called a cycle.
var i = 0;
We initiate the i variable. It is used as a counter.
while (i < 10) {
...
}
The expression inside the round brackets following the while
keyword is the second phase: the testing. The statements in the body are
executed until the expression is evaluated to false.
i++;
This is the last, third phase of the while loop: the updating. We
increment the counter. Note that improper handling of the while
loops may lead to endless cycles.
$ dart main.dart 55
Dart do-while loop
The do-while loop tests its condition after the body, so the body
is always executed at least once.
void main() {
var n = 10;
do {
print('n = $n');
n++;
} while (n < 10);
}
Although the condition n < 10 is false from the start, the body
runs once.
$ dart main.dart n = 10
Dart classic for loop
The classic for loop was taken from the C programming language. A for loop has also three phases: initialization, condition and code block execution, and incrementation.
void main() {
var sum = 0;
for (var i = 0; i < 10; i++) {
sum += i;
}
print(sum);
}
In this example, we sum values 0..9 and print the result to the console.
for (var i = 0; i < 10; i++) {
sum += i;
}
In the first phase, we initiate the counter i to zero. This phase
is done only once. Next comes the condition i < 10. If the
condition is met, the statement inside the for block is executed.
In the third phase the counter is increased. Now we repeat the phases 2 and 3
until the condition is not met and the for loop is left. In our case, when the
counter i is equal to 10, the for loop stops executing.
$ dart main.dart 45
Dart for-in loop
The for-in form enables us to loop over an iterable easily.
It is similar to the forEach function.
void main() {
final words = ['sky', 'load', 'cup', 'tea', 'rock', 'plate'];
for (final word in words) {
print(word);
}
}
In the example, we define a list of words. With for-in we loop
over the list and print all words.
$ dart main.dart sky load cup tea rock plate
Dart break and continue
The break statement terminates the execution of a loop created
by while or for. The continue statement
skips the rest of the current cycle and starts the next one.
import 'dart:math';
void main() {
const max = 30;
final rnd = Random(7);
while (true) {
final value = rnd.nextInt(max);
print(value);
if (value == 22) {
break;
}
}
}
We define an endless while loop. We use the break
statement to get out of this loop. We choose a random value from 0 to 29 and
print it. If the value equals 22, we finish the loop. The generator is seeded
with 7 to make the output reproducible.
$ dart main.dart 10 17 8 9 6 8 22
void main() {
for (var i = 1; i <= 10; i++) {
if (i.isEven) {
continue;
}
print(i);
}
}
In this example, we print the odd numbers up to 10. When the number is even,
continue skips the print call.
$ dart main.dart 1 3 5 7 9
Dart labels
A label lets break and continue target an outer loop.
void main() {
outer:
for (var i = 1; i <= 3; i++) {
for (var j = 1; j <= 3; j++) {
if (j == 3) continue outer;
if (i == 3) break outer;
print('i=$i, j=$j');
}
}
}
When j reaches 3, continue outer goes on with the
next cycle of the outer loop. When i is 3, break outer
leaves both loops.
$ dart main.dart i=1, j=1 i=1, j=2 i=2, j=1 i=2, j=2
Source
In this article we have covered control flow in Dart.
Author
List all Dart tutorials.