You can control the flow of your Dart code using any of the following:
-
if
andelse
-
for
loops -
while
anddo
-while
loops -
break
andcontinue
-
switch
andcase
assert
You can also affect the control flow using try-catch
and throw
, as
explained in Exceptions.
If and else
Dart supports if
statements with optional else
statements, as the
next sample shows. Also see conditional expressions.
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
The statement conditions must be expressions that evaluate to boolean values, nothing else. See Booleans for more information.
For loops
You can iterate with the standard for
loop. For example:
var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
message.write('!');
}
Closures inside of Dart’s for
loops capture the value of the index,
avoiding a common pitfall found in JavaScript. For example, consider:
var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
for (final c in callbacks) {
c();
}
The output is 0
and then 1
, as expected. In contrast, the example
would print 2
and then 2
in JavaScript.
If the object that you are iterating over is an Iterable (such as List or Set)
and if you don’t need to know the current iteration counter,
you can use the for-in
form of iteration:
for (final candidate in candidates) {
candidate.interview();
}
Iterable classes also have a forEach() method as another option:
var collection = [1, 2, 3];
collection.forEach(print); // 1 2 3
While and do-while
A while
loop evaluates the condition before the loop:
while (!isDone()) {
doSomething();
}
A do
-while
loop evaluates the condition after the loop:
do {
printLine();
} while (!atEndOfPage());
Break and continue
Use break
to stop looping:
while (true) {
if (shutDownRequested()) break;
processIncomingRequests();
}
Use continue
to skip to the next loop iteration:
for (int i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
if (candidate.yearsExperience < 5) {
continue;
}
candidate.interview();
}
You might write that example differently if you’re using an
Iterable
such as a list or set:
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
Switch and case
Switch statements in Dart compare integer, string, or compile-time
constants using ==
. The compared objects must all be instances of the
same class (and not of any of its subtypes), and the class must not
override ==
.
Enumerated types work well in switch
statements.
Each non-empty case
clause ends with a break
statement, as a rule.
Other valid ways to end a non-empty case
clause are a continue
,
throw
, or return
statement.
Use a default
clause to execute code when no case
clause matches:
var command = 'OPEN';
switch (command) {
case 'CLOSED':
executeClosed();
break;
case 'PENDING':
executePending();
break;
case 'APPROVED':
executeApproved();
break;
case 'DENIED':
executeDenied();
break;
case 'OPEN':
executeOpen();
break;
default:
executeUnknown();
}
The following example omits the break
statement in a case
clause,
thus generating an error:
var command = 'OPEN';
switch (command) {
case 'OPEN':
executeOpen();
// ERROR: Missing break
case 'CLOSED':
executeClosed();
break;
}
However, Dart does support empty case
clauses, allowing a form of
fall-through:
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // Empty case falls through.
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
If you really want fall-through, you can use a continue
statement and
a label:
var command = 'CLOSED';
switch (command) {
case 'CLOSED':
executeClosed();
continue nowClosed;
// Continues executing at the nowClosed label.
nowClosed:
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
A case
clause can have local variables, which are visible only inside
the scope of that clause.
Assert
During development, use an assert
statement—assert(condition, optionalMessage)
;—to
disrupt normal execution if a boolean condition is false.
You can find examples of assert statements throughout this tour.
Here are some more:
// Make sure the variable has a non-null value.
assert(text != null);
// Make sure the value is less than 100.
assert(number < 100);
// Make sure this is an https URL.
assert(urlString.startsWith('https'));
To attach a message to an assertion,
add a string as the second argument to assert
(optionally with a trailing comma):
assert(urlString.startsWith('https'),
'URL ($urlString) should start with "https".');
The first argument to assert
can be any expression that
resolves to a boolean value. If the expression’s value
is true, the assertion succeeds and execution
continues. If it’s false, the assertion fails and an exception (an
AssertionError
) is thrown.
When exactly do assertions work? That depends on the tools and framework you’re using:
- Flutter enables assertions in debug mode.
- Development-only tools such as [
webdev serve
][] typically enable assertions by default. - Some tools, such as
dart run
and [dart compile js
][] support assertions through a command-line flag:--enable-asserts
.
In production code, assertions are ignored, and
the arguments to assert
aren’t evaluated.