Control flow statements
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 dart-tour-operators ">conditional expressions.
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
Unlike JavaScript, conditions must use boolean values, nothing else. See dart-tour-built-in-types ">Booleansfor 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));
}
callbacks.forEach((c) => 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, you can use the forEach()
method. Using forEach()
is a good option if you don’t need to know the current iteration counter:
candidates.forEach((candidate) => candidate.interview());
Iterable classes such as List
and Set
also support the for-in
form of iteration:
var collection = [0, 1, 2];
for (var x in collection) {
print(x); // 0 1 2
}
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.
Note: Switch statements in Dart are intended for limited circumstances, such as in interpreters or scanners.
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';
witch (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. 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
.
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 dartdevc typically enable assertions by default.
Some tools, such as dart and dart2js, support assertions through a command-line flag: --enable-asserts
.
In production code, assertions are ignored, and the arguments to assert
aren’t evaluated.