Прямые ссылки на публичные уроки для быстрого старта и стабильной индексации lesson-страниц.
Цикл for служит для перебора значений по коллекциям: спискам или диапазонам чисел. Сначала разберём диапазоны, затем перейдём к конструкции for.
Диапазон — объект, содержащий числа в заданном промежутке. Создаются с помощью .. или ключевого слова until. Разница: при until последнее значение в диапазон не включается.
val range1 = 42..442 // включает 442 val range2 = 42 until 442 // не включает 442
Диапазоны бывают разных типов — Long, Char, Double, Float:
val range1: IntRange = 42 until 442 val range2: IntRange = 42..442 val range3: LongRange = 42L..442L val range4: CharRange = 'a'..'z' val range5: ClosedRange<Double> = 42.1..442.1 val range6: ClosedRange<Float> = 42.1f..442.1f
Важно: диапазоны типа
ClosedRange(Float, Double) нельзя использовать для итерации в циклеfor.CharRangeитерируется корректно, так как символы кодируются целыми числами.
Диапазон можно рассматривать как прогрессию — ряд увеличивающихся или уменьшающихся чисел. Функция step задаёт шаг итерации и превращает диапазон в тип IntProgression:
val range7: IntProgression = 42..442 step 2
По умолчанию шаг равен 1.
Для диапазона с убывающими значениями вместо .. используется downTo. Результат также является IntProgression:
val range8: IntProgression = 442 downTo 42 step 2
Операторы in и !in проверяют, входит ли значение в диапазон:
in — возвращает true, если значение присутствует в диапазоне!in — возвращает true, если значение отсутствует в диапазонеval a = 52 in range1 // true val b = 52 !in range1 // false println(a) println(b)
| Ситуация | Рекомендуемый цикл |
|---|---|
| Количество итераций известно заранее | for |
| Количество итераций заранее неизвестно | while / do-while |
Для обратного отсчёта из предыдущего урока количество итераций чётко определено (5 секунд), поэтому for — более подходящий и лаконичный выбор:
for (i in 5 downTo 1) { println("Реклама закончится через $i") Thread.sleep(1000) }
i — переменная, создаваемая в рамках текущего цикла. Она принимает текущее значение из перебираемой коллекции на каждой итерации. Название произвольное. В отличие от while, вспомогательная переменная-счётчик вне цикла не нужна.
В условии цикла for указывается коллекция для перебора: список, массив или диапазон. 5 downTo 1 создаёт убывающую прогрессию — i уменьшается на 1 на каждом шаге. При использовании .. или until значение i увеличивается.
Шаг по умолчанию равен 1. Его можно задать прямо в условии цикла:
for (i in range2 step 8) { println(i) }
Если цикл не нужно выполнять до конца (например, искомое значение уже найдено), используются операторы перехода: break, continue и return.
Полностью завершает работу цикла. Программа продолжает выполнение с кода, расположенного после цикла.
Пример: пользователь нажал кнопку «Пропустить» на i == 3:
for (i in 5 downTo 1) { if (i == 3) { println("Пользователь нажал на кнопку \"Пропустить\"") break } println("Реклама закончится через $i") Thread.sleep(1000) } println("Продолжение работы программы вне цикла")
Когда i становится равным 3, цикл прерывается и выполнение переходит к println после него.
В примере выше слово "Пропустить" обёрнуто в экранированные кавычки \". Экранирование — замена управляющих символов на текстовые подстановки с помощью \. Без него компилятор воспринял бы внутреннюю кавычку как конец строки и выдал ошибку.
Прерывает текущую итерацию и переходит к следующей. Сам цикл продолжает работу.
for (i in 5 downTo 1) { if (i == 3) { println("i == 3, i не будет распечатана") continue } println("Реклама закончится через $i") Thread.sleep(1000) }
Вывод:
Реклама закончится через 5 Реклама закончится через 4 i == 3, i не будет распечатана Реклама закончится через 2 Реклама закончится через 1
При i == 3 выполняется только код до continue — строка с рекламным счётчиком пропускается, цикл переходит к следующему шагу.
Завершает выполнение всей функции, в которой находится. В случае с main() — полностью останавливает программу.
for (i in 5 downTo 1) { if (i == 3) { return } println("Реклама закончится через $i") Thread.sleep(1000) } println("Продолжение работы программы вне цикла")
Вывод:
Реклама закончится через 5 Реклама закончится через 4
Как только i становится 3, вызывается return и main() завершается. Сообщение «Продолжение работы программы вне цикла» не печатается.