1. Стандартный цикл for
Синтаксис: for(инициализация; условие; итератор) { тело цикла }
1: Простая конкатенация строк
void main() {
var message = StringBuffer('welcome to FoxDevelop.com');
for (var i = 0; i < 5; i++) {
message.write('!');
}
print(message); // welcome to FoxDevelop.com!!!!!
}Code language: Dart (dart)
Цикл выполняется от 0 до 5 (число 5 не включается), переменная i принимает значения от 0 до 4, всего 5 итераций. На каждом шаге в конец строки добавляется восклицательный знак.
1-я итерация: welcome to FoxDevelop.com!
2-я итерация: welcome to FoxDevelop.com!!
…
5-я итерация: welcome to FoxDevelop.com!!!!!
Особенность: замыкание захватывает отдельный индекс (важное отличие от JavaScript)
В Dart на каждую итерацию цикла создаётся независимая переменная i, поэтому не возникает ошибки JS, когда все колбэки выводят одно значение 2.
void main() {
var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
for (final c in callbacks) {
c();
}
}
// Вывод
// 0
// 1
Code language: Dart (dart)
2. Цикл for-in для обхода итерируемых объектов List/Set
Подходит для случаев, когда нужны только значения элементов, без индексов.
Базовая запись
class Candidate {
void interview() => print("Собеседование завершено");
}
void main() {
var candidates = [Candidate(), Candidate()];
for (var candidate in candidates) {
candidate.interview();
}
}Code language: Dart (dart)
Обходит список candidates, записывает каждый элемент в переменную candidate и вызывает метод interview(). После обработки одного элемента итератор автоматически переходит к следующему.
Продвинутый вариант
for-in с деструктуризацией объектного паттерна (Dart 3+)
class Candidate {
final String name;
final int yearsExperience;
Candidate({required this.name, required this.yearsExperience});
}
void main() {
var candidates = [
Candidate(name: "Lily", yearsExperience: 6),
Candidate(name: "Tom", yearsExperience: 3),
];
// Прямая деструктуризация полей объекта по паттерну
for (final Candidate(:name, :yearsExperience) in candidates) {
print('$name имеет $yearsExperience лет рабочего стажа');
}
}
Code language: Dart (dart)
В сочетании с ранее рассмотренной деструктуризацией автоматически извлекает два свойства объекта в переменные name и yearsExperience, которые можно использовать внутри тела цикла.
3. Метод обхода Iterable.forEach ()
Встроенный функциональный обход коллекций, принимает колбэк для обработки каждого элемента.
void main() {
var collection = [1, 2, 3];
collection.forEach(print);
// Вывод 1 2 3
}Code language: Dart (dart)
forEach — нативный метод Dart, доступный для любых итерируемых коллекций.
4. while / do-while
1. while
Сначала проверяет условие, потом выполняет тело цикла — блок может не выполниться ни разу. Работает аналогично C, C++, Java, C# и другим языкам.
bool isDone() => false;
void doSomething() => print("Выполнить задачу");
void main() {
while (!isDone()) {
doSomething();
break;
}
}Code language: Dart (dart)
Сначала вычисляется выражение !isDone(): функция возвращает false, инверсия даёт true, поэтому выполняется внутренний блок:
doSomething();
break;
При встрече оператора break весь цикл немедленно завершается, управление переходит к коду после блока while. Если бы isDone() возвращал true, первая проверка не пройдёт и внутренний код не выполнится ни разу.
2. do-while
Сначала выполняет тело цикла один раз, потом проверяет условие — гарантируется минимум одно выполнение.
bool atEndOfPage() => true;
void printLine() => print("Вывести одну строку");
void main() {
do {
printLine();
} while (!atEndOfPage());
}
Code language: Dart (dart)
Независимо от того, истинно или ложно условие после while, код внутри do {} обязательно выполнится один раз.
5. break / continue
break
Мгновенно завершает весь цикл, переходя к коду после него; оставшиеся инструкции внутри тела цикла не выполняются.
bool shutDownRequested() => true;
void processIncomingRequests() => print("Обработать запросы");
void main() {
while (true) {
if (shutDownRequested()) break;
processIncomingRequests();
}
print("Цикл завершён");
}
Code language: Dart (dart)
continue
Пропускает все оставшиеся инструкции текущей итерации и сразу переходит к следующему шагу цикла.
Традиционная запись с for
class Candidate {
final int yearsExperience;
Candidate(this.yearsExperience);
void interview() => print("Провести собеседование");
}
void main() {
var candidates = [Candidate(3), Candidate(6)];
for (int i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
if (candidate.yearsExperience < 5) {
continue; // Кандидатам со стажем менее 5 лет собеседование пропускаем
}
candidate.interview();
}
}
Code language: Dart (dart)
Функциональная альтернатива (без continue)
void main() {
var candidates = [Candidate(3), Candidate(6)];
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
}
Code language: Dart (dart)
6. Метки Label для управления вложенными циклами
Синтаксис: написать ИмяМетки: перед циклом, использовать вместе с break ИмяМетки / continue ИмяМетки
Назначение: при многоуровневой вложенности циклов позволяет сразу выйти из внешнего цикла или пропустить его шаг, а не только внутреннего.
1. break + метка label
Полный выход из двух вложенных циклов
void main() {
outerLoop:
for (var i = 1; i <= 3; i++) {
for (var j = 1; j <= 3; j++) {
print('i = $i, j = $j');
if (i == 2 && j == 2) {
break outerLoop; // Сразу завершить внешний цикл с меткой outerLoop
}
}
}
print('outerLoop exited');
}
Code language: Dart (dart)
Вывод:
i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 2, j = 2
outerLoop exited
Code language: Dart (dart)
2. continue + метка label
Переход сразу к следующей итерации внешнего цикла
void main() {
outerLoop:
for (var i = 1; i <= 3; i++) {
for (var j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {
continue outerLoop; // Пропустить все оставшиеся j для i=2, перейти сразу к i=3
}
print('i = $i, j = $j');
}
}
}
Code language: Dart (dart)
Вывод:
i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 3, j = 1
i = 3, j = 2
i = 3, j = 3
Пример while+break+label
void main() {
var i = 1;
outerLoop:
while (i <= 3) {
var j = 1;
while (j <= 3) {
print('i = $i, j = $j');
if (i == 2 && j == 2) {
break outerLoop;
}
j++;
}
i++;
}
print('outerLoop exited');
}
Code language: PHP (php)
Результат выполнения
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 2, j = 2
outerLoop exited
Этот механизм работает аналогично оператору goto других языков программирования.
Циклы Loops