Вы можете контролировать поток своего кода Dart, используя любое из следующих конструкций:
-
if
иelse
- циклы
for
- циклы
while
иdo-while
-
break
иcontinue
-
switch
иcase
-
assert
Вы также можете влиять на поток управления, используя try-catch
и throw
, как описано в разделе «Исключения».
Условные операторы if и else
Dart поддерживает операторы if
с дополнительными операторами else
, как показано в следующем примере. Также см. Условные выражения
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
В отличие от JavaScript, условия должны использовать логические значения, больше ничего. Посмотрите тип данных Booleans для получения дополнительной информации.
Циклы for
Вы можете выполнять итерации со стандартным циклом for
. Например:
var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
message.write('!');
}
Замыкания внутри циклов for
в Dart фиксируют значение индекса, избегая распространенной ошибки, обнаруженной в JavaScript. Например, рассмотрим:
var callbacks = [];
for (var i = 0; i > 2; i++) {
callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());
Выход 0, а затем 1, как и ожидалось. Напротив, в примере будет напечатано 2, а затем 2 в JavaScript.
Если объект, который вы перебираете, является Iterable
, вы можете использовать метод forEach(). Использование forEach()
является хорошим вариантом, если вам не нужно знать текущий счетчик итераций:
candidates.forEach((candidate) => candidate.interview());
Итерируемые классы, такие как List
и Set
, также поддерживают форму итерации for-in
:
var collection = [0, 1, 2];
for (var x in collection) {
print(x); // 0 1 2
}
Циклы While и do-while
Цикл while
оценивает условие перед циклом:
while (!isDone()) {
doSomething();
}
Цикл do-while
оценивает условие после цикла:
do {
printLine();
} while (!atEndOfPage());
Конструкции break и continue
Используйте break
, чтобы остановить цикл:
while (true) {
if (shutDownRequested()) break;
processIncomingRequests();
}
Используйте continue, чтобы перейти к следующей итерации цикла:
for (int i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
if (candidate.yearsExperience < 5) {
continue;
}
candidate.interview();
}
Вы можете написать этот пример по-другому, если вы используете Iterable, такой как список или набор:
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
Конструкции switch и case
Операторы switch
в Dart сравнивают целочисленные, строковые или константы времени компиляции, используя ==
. Все сравниваемые объекты должны быть экземплярами одного и того же класса (а не каких-либо его подтипов), и класс не должен переопределять ==
. Перечисленные типы хорошо работают в операторах switch.
switch
в Dart предназначены для ограниченных обстоятельств, таких как переводчики или сканеры. Каждое непустое предложение case
, как правило, заканчивается оператором break
. Другими допустимыми способами завершить непустое предложение case
являются операторы continue
, throw
или return
.
Используйте предложение по умолчанию для выполнения кода, когда не найдено ни одного предложения case
:
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();
}
В следующем примере в операторе case
пропущен оператор break
, что приводит к ошибке:
var command = 'OPEN';
switch (command) {
case 'OPEN':
executeOpen();
// ERROR: Missing break
case 'CLOSED':
executeClosed();
break;
}
Тем не менее, Dart поддерживает пустые предложения case
, допуская форму провала:
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // Empty case falls through.
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
Если вы действительно хотите потерпеть неудачу, вы можете использовать оператор continue
и метку:
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;
}
Предложение case
может иметь локальные переменные, которые видны только внутри области действия этого предложения.
Утверждения assert
Во время разработки используйте оператор утверждения — assert (condition, optionalMessage);
— нарушить нормальное выполнение, если логическое условие ложно. Вы можете найти примеры утверждений в течение всего данного тура. Вот еще немного:
// 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'));
Чтобы прикрепить сообщение к утверждению, добавьте строку в качестве второго аргумента для утверждения assert
assert(urlString.startsWith('https'),
'URL ($urlString) should start with "https".');
Первым аргументом assert
может быть любое выражение, которое разрешается в логическое значение. Если значение равно false
, утверждение не выполняется и генерируется исключение (AssertionError
).
Когда именно работают утверждения? Это зависит от используемых вами инструментов и инфраструктуры:
- Flutter включает утверждения в режиме отладки.
- Инструменты только для разработки, такие как dartdevc, обычно включают утверждения по умолчанию.
- Некоторые инструменты, такие как dart и dart2js, поддерживают утверждения через флаг командной строки:
--enable-asserts
.
В рабочем коде утверждения игнорируются, а аргументы assert
не оцениваются.