Циклы позволяют в зависимости от определенного условия выполнять некоторые действия множество раз. Фактически в Go есть только один цикл - цикл for, который может принимать разные формы. Этот цикл имеет следующее формальное определение:
for [инициализация счетчика]; [условие]; [изменение счетчика]{ // действия }
Например, выведем с помощью цикла квадраты чисел:
package main import "fmt" func main() { for i := 1; i < 10; i++{ fmt.Println(i * i) } }
Объявление цикла for разбивается на три части. Вначале идет инициализация счетчика: i := 1
. Фактически она представляет
объявление переменной, которая будет использоваться внутри цикла. В данном случае это счетчик i, начальное значение которого равно 1.
Вторая часть представляет условие: i < 10
. Пока это условие истинно, то есть возвращает true, будет продолжаться цикл.
Третья часть представляет изменение (увеличение) счетчика на единицу.
В теле цикла на консоль выводится квадрат числа i.
Таким образом, цикл сработает 9 раз, пока значение i не станет равным 10. И каждый раз это значение будет увеличиваться на 1. Каждый отдельный проход цикла называется итерацией. То есть в данном случае будет 9 итераций. В итоге мы получим следующий консольный вывод:
1 4 9 16 25 36 49 64 81
Нам необязательно указывать все условия при объявлении цикла. Например, можно вынести объявление переменной вовне:
var i = 1 for ; i < 10; i++{ fmt.Println(i * i) }
Можно убрать изменение счетчика в само тело цикла и оставить только условие:
var i = 1 for ; i < 10;{ fmt.Println(i * i) i++ }
Если цикл использует только условие, то его можно сократить следующим образом:
var i = 1 for i < 10{ fmt.Println(i * i) i++ }
Циклы могут быть вложенными, то есть располагаться внутри других циклов. Например, выведем на консоль таблицу умножения:
package main import "fmt" func main() { for i := 1; i < 10; i++{ for j := 1; j < 10; j++{ fmt.Print(i * j, "\t") } fmt.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
Для перебора массивов можно использовать следующую форму цикла for:
for индекс, значение := range массив{ // действия }
При переборе мы можем по отдельности получить индекс элемента в массиве и значение этого элемента. Например, перебирем массив строк:
var users = [3]string{"Tom", "Alice", "Kate"} for index, value := range users{ fmt.Println(index, value) }
Консольный вывод:
0 Tom 1 Alice 2 Kate
Если мы не планируем использовать значения или индексы элементов, то мы можем вместо них указать прочерк. Например, нам не нужны индексы:
for _, value := range users{ fmt.Println(value) }
Но также для перебора массива можно использовать и стандартную версию цикла for:
var users = [3]string{"Tom", "Alice", "Kate"} for i:= 0; i < len(users); i++{ fmt.Println(users[i]) }
В данном случае счетчик i играет роль индекса. Цикл выполняется, пока счетчик i не станет равным длине массива, которую можно получить с помощью функции len()
Может возникнуть ситуация, когда нам надо при определенных условиях завершить текущую итерацию цикла, не выполнять все инструкции цикла, а сразу перейти к следующей итерации. В этом случае можно использовать оператор continue. Например, в массиве могу быть, как положительные, так и отрицательные числа. Допустим, нам нужна сумма только положительных чисел, поэтому, если нам встретится отрицательное число, мы можем просто перейти к следующей итерации с помощью continue:
var numbers = [10]int{1, -2, 3, -4, 5, -6, -7, 8, -9, 10} var sum = 0 for _, value := range numbers{ if value < 0{ continue // переходим к следующей итерации } sum += value } fmt.Println("Sum:", sum) // Sum: 27
Оператор break полностью осуществляет выход из цикла:
var numbers = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} var sum = 0 for _, value := range numbers{ if value > 4{ break // если число больше 4 выходим из цикла } sum += value } fmt.Println("Sum:", sum) // Sum: 10