В одном из предыдущих уроков мы уже рассмотрели циклы while. Мы также изучили интервалы. Пришло время взглянуть на особенности цикла for в Kotlin. Вероятно, это самый распространенный вид циклов. Вы будете использовать его довольно часто.
Содержание статьи
Синтаксис цикла for в Kotlin
Цикл for создается следующим образом:
| 1 2 3 | for (<CONSTANT> in <RANGE>) { <LOOP CODE> } |
Цикл начинается с ключевого слова for, за которым следует название константы цикла (скоро мы поговорим и о ней), по середине у нас слово in и сам интервал цикла через которого мы пройдемся. Далее представлен пример:
| 1 2 3 4 5 6 7 8 9 10 | fun main() { val count = 10 var sum = 0 for (i in 1..count) { sum += i } print(sum) } |
В приведенном выше коде, цикл for проходит через интервал от 1 до count. На первой итерации i будет равняться первому элементу интервала: 1. Каждый раз, проходя по циклу циклу, переменная i будет увеличиваться до тех пор, пока не сравняется с count. Цикл выполнится в последний раз, а затем завершится.
На заметку: Если вы использовали полуоткрытый интервал until, последней итерацией переменной
iбудетcount - 1.
Внутри цикла, значение из i добавляется к переменной sum. Он запускается 10 раз для вычисления последовательности 1 + 2 + 3 + 4 + 5 + ... до 10.
Далее представлены значения i и переменной sum для каждой итерации:
- Начало итерации 1:
i= 1,sum= 0 - Начало итерации 2:
i= 2,sum= 1 - Начало итерации 3:
i= 3,sum= 3 - Начало итерации 4:
i= 4,sum= 6 - Начало итерации 5:
i= 5,sum= 10 - Начало итерации 6:
i= 6,sum= 15 - Начало итерации 7:
i= 7,sum= 21 - Начало итерации 8:
i= 8,sum= 28 - Начало итерации 9:
i= 9,sum= 36 - Начало итерации 10:
i= 9,sum= 45 - После итерации 10:
sum= 55
Говоря об области видимости, константа i видна только внутри области видимости цикла for, а это значит, что она недоступна за пределами цикла.
На заметку: Если вы разбираетесь в математике, вы могли заметить, что в этом примере вычисляются треугольные числа.
Иногда требуется пройтись по циклу только определенное количество раз, и константа цикла не нужна вообще. В данном случае цикл repeat используется следующим образом:
| 1 2 3 4 5 6 7 8 9 10 11 12 | fun main() { var sum = 1 var lastSum = 0 repeat(10) { val temp = sum sum += lastSum lastSum = temp } print(lastSum) } |
В интервале можно указать шаг. К примеру, подсчитать сумму нечетных чисел:
| 1 2 3 4 5 6 7 8 9 10 | fun main() { var sum = 0 val count = 10 for (i in 1..count step 2) { sum += i } print(sum) } |
Здесь внутри цикла for есть оператор step. Цикл будет выполняться только для значений, на которые выпадает данный шаг. В этом случае вместо того, чтобы проходить через каждое значение в интервале, цикл будет проходить через все остальные значения. Таким образом, i всегда будет нечетным, потому что начальное значение равно 1.
В цикле for также можно использовать обратный отсчет, используя downTo. В таком случае, если count имеет значение 10, цикл будет перебирать значения (10, 8, 6, 4, 2).
| 1 2 3 4 5 6 7 8 9 10 | fun main() { var sum = 0 val count = 10 for (i in count downTo 1 step 2) { sum += i } print(sum) } |
Маркированные операторы continue и break
Иногда требуется пропустить итерацию цикла для отдельного случая, не прерывая его полностью. Это можно сделать с помощью оператора continue, который сразу завершает текущую итерацию цикла и запускает следующую. Оператор continue дает более высокий уровень контроля, позволяя решать, где и когда пропустить итерацию.
Возьмем пример сетки 8 на 8, где каждая ячейка содержит значение строки, умноженное на столбец. Это очень похоже на таблицу умножения, не так ли?

Предположим, нужно посчитать сумму всех клеток, кроме нечетных рядов, как показано ниже:

Через цикл for это делается следующим образом:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | fun main() { var sum = 0 for (row in 0 until 8) { if (row % 2 == 0) { continue } for (column in 0 until 8) { sum += row * column } } print("Результат: $sum") } |
Строка четная если результат деления номера строки на 2 равен 0. В этом случае continue заставляет цикл for переходить к следующей строке.
Оператор break, который мы уже использовали при изучении цикла while, можно использовать с циклами for и его использование прерывает работу цикла полностью. Как и break, continue работает как с циклами for, так и с циклами while.
Во втором примере кода, будет вычислена сумма всех ячеек, за исключением тех, в которых столбец больше или равен строке.
Должны складываться следующие ячейки:

С помощью цикла for это можно сделать следующим образом:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | fun main() { var sum = 0 rowLoop@ for (row in 0 until 8) { columnLoop@ for (column in 0 until 8) { if (row == column) { continue@rowLoop } sum += row * column } } print("Результат: $sum") } |
Предыдущий блок кода использует маркер, помечая два цикла как rowLoop и columnLoop соответственно. Когда строка равна столбцу внутри цикла columnLoop, внешний цикл rowLoop будет продолжен.
Можно использовать такие маркированные операторы с break, чтобы выйти из определенного цикла. Обычно break и continue применяются в цикле внутри цикла. Поэтому маркированные операторы нужно использовать, когда требуется манипулировать главным циклом в теле которого мы находимся.
Задания для проверки
1. Создайте константу range, ее интервал будет от 1 до 10 включительно. Напишите цикл for, который выполняет итерацию по этому интервалу и выводит квадрат каждого числа;
2. Напишите цикл for для итерации того же интервала, что и в приведенном выше задании, и выведите квадратный корень из каждого числа.
3. Выше вы видели цикл for, который перебирает только четные строки из сетки, например:
| 1 2 3 4 5 6 7 8 9 10 11 12 | fun main() { var sum = 0 for (row in 0 until 8) { if (row % 2 == 0) { continue } for (column in 0 until 8) { sum += row * column } } } |
Измените код, чтобы он использовал шаг step с первым циклом for, чтобы пропускать четные строки вместо использования continue. Убедитесь, что сумма равна 448 как в изначальном примере.
