Циклы представляют вид управляющих конструкций, которые позволяют в зависимости от определенных условий выполнять некоторое действие множество раз.
Цикл for пробегается по всем элементам коллекции. В этом плане цикл for в Kotlin эквивалентен циклу for-each
в ряде других языков программирования.
Его формальная форма выглядит следующим образом:
for(переменная in последовательность){ выполняемые инструкции }
Например, выведем все квадраты чисел от 1 до 9, используя цикл for:
for(n in 1..9){ print("${n * n} \t") }
В данном случае перебирается последовательность чисел от 1 до 9. При каждом проходе цикла (итерации цикла) из этой последовательности будет извлекаться элемент и помещаться в переменную n. И через переменную n можно манипулировать значением элемента. То есть в данном случае мы получим следующий консольный вывод:
1 4 9 16 25 36 49 64 81
Циклы могут быть вложенными. Например, выведем таблицу умножения:
for(i in 1..9){ for(j in 1..9){ print("${i * j} \t") } println() }
В итоге на консоль будет выведена следующая таблица умножения:
1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
Цикл while повторяет определенные действия пока истинно некоторое условие:
var i = 10 while(i > 0){ println(i*i) i--; }
Здесь пока переменная i больше 0, будет выполняться цикл, в котором на консоль будет выводиться квадрат значения i.
В данном случае вначале проверяется условие (i > 0) и если оно истинно (то есть возвращает true), то выполняется цикл. И вполне может быть ситуация, когда к началу выполнения цикла условие не будет выполняться. Например, переменная i изначально меньше 0, тогда цикл вообще не будет выполняться.
Есть и другая форма цикла while - do..while:
var i = -1 do{ println(i*i) i--; } while(i > 0)
В данном случае вначале выполняется блок кода после ключевого слова do, а потом оценивается условие после while. Если условие истинно, то повторяется выполнение блока после do. То есть несмотря на то, что в данном случае переменная i меньше 0 и она не соответствует условию, тем не менее блок do выполнится хотя бы один раз.
Иногда при использовании цикла возникает необходимость при некоторых условиях не дожидаться выполнения всех инструкций в цикле, перейти к новой итерации. Для этого можно использовать оператор continue:
for(n in 1..8){ if(n == 5) continue; println(n * n) }
В данном случае когда n будет равно 5, сработает оператор continue. И последующая инструкция, которая выводит на консоль квадрат числа, не будет выполняться. Цикл перейдет к обработке следующего элемента в массиве
Бывает, что при некоторых условиях нам вовсе надо выйти из цикла, прекратить его выполнение. В этом случае применяется оператор break:
for(n in 1..5){ if(n == 5) break; println(n * n) }
В данном случае когда n окажется равен 5, то с помощью оператора break будет выполнен выход из цикла. Цикл полностью завершится.
Однако следует помнить, что оператор bresk выводит только из текущего цикла, где он вызывается. Например, возьмем следующую конструкцию с внешним и внутренним циклами:
fun main() { for(i in 1..3){ for(j in 1..3){ if(j == 3) break; println("Hello") } } }
Сколько раз здесь будет выведена строка "Hello"? Очевидно 6 раз.
Hello Hello Hello Hello Hello Hello
Каждый раз во внутреннем цикле j окажется равна 3, произойдет переход к новой итерации внешнего цикла по i. Но что если нам надо вообще выйти из всех циклов, в том числе и из внешнего? Наиболее простым в данном случае способом будет использование меток:
fun main() { outerloop@ for(i in 1..3){ for(j in 1..3){ if(j == 3) break@outerloop; println("Hello") } } }
В данном случае внешний цикл маркирован меткой outerloop
. Название метки произвольное, единственное, что заврешается символом @
. И кода во внутреннем цикле будет
выполняться условие j == 3
оператор break выйдет из цикла, предваряемого меткой outerloop
if(j == 3) break@outerloop;