Давайте дружить в Телеграме: рассказываем про новые фичи, общаемся в комментах, прислушиваемся к вашим идеям Подписаться

Циклы for в языке программирования Go

Команда Timeweb Cloud
Команда Timeweb Cloud
Наши инженеры, технические писатели, редакторы и маркетологи
18 марта 2022 г.
1227
7 минут чтения
Средний рейтинг статьи: 5

New Documentation

Цикл — это блок кода, который работает до тех пор, пока не будет выполнено заданное условие или не будет пройденное необходимое число повторений. Использовать циклы удобно для решения задач, в которых многократно повторяются одни и те же действия.

Например, у вас есть список режиссеров. Вам нужно вытащить фамилию каждого режиссера и вывести ее на экран. Чтобы не приходилось обращаться вручную к каждому элементу списка, удобнее запустить цикл (loop). Он пройдется по всему списку и выведет каждую фамилию на экран.

Циклы for В Языке Программирования Go (1)

Циклы в Go

В языке Go есть только циклы for. Никаких while и do while, как в некоторых других языках. Похожие концепции реализованы с помощью того же for. Это сделано для того, чтобы код был более читабельным. Разработчикам не нужно думать о том, какую стратегию выбрать. Если нужно многократно выполнить какие-то действия, есть for, который можно использовать по-разному.

Давайте посмотрим, как создавать циклы для решения некоторых задач.

ForClause

Структура кода у ForClause простая. Он состоит из условия и тела. Код, который находится в теле, выполняется, если состояние равно true

Пример:

for i := 0; i < 6; i++ {
  fmt.Println(i)
}

Здесь  i := 0 — это инициирующий оператор. Он говорит, откуда начинать выполнять loop. Дальше идет i < 6. Это состояние. Если оно равно True, код внутри цикла for выполняется. Конструкция fmt.Println(i) последовательно выводит цифры от 0 до 5. Каждый раз цифра увеличивается на 1 — это задано постоператором i++

Логика простая. Код начинает выполняться с 0. 0 меньше 6, состояние равно True. На экране отображается 0. Дальше срабатывает постоператор i++, который прибавляет к текущему значению i единицу: 0 + 1 = 1. 1 меньше 6, состояние равно True. Теперь отображается 1, срабатывает постоператор i++. Дальше i = 2 (1 + 1) — продолжается выполнение одной и той же работы. 

Так будет продолжаться до тех пор, пока i не станет равным 6. В таком случае состояние перестанет быть равным True, потому что 6 не меньше 6. Число 6 на экран не выводится. Функция завершает работу. 

В итоге:

0
1
2
3
4
5

Необязательно начинать с нуля и заканчивать заданным значением. For в Go позволяет гибко управлять логикой решения задачи. 

Величина инициирующего оператора может быть любой. Шаг постоператора тоже настраивается. Например, вы можете начать со 100 и выводить каждое десятое число:

for i := 100; i < 150; i = i + 10 {
  fmt.Println(i)
}

Вы получите:

100
110
120
130
140

150 уже не выводится. Но если немного изменить условие, то вы получите и это число тоже:

for i := 100; i <= 150; i = i + 10 {
  fmt.Println(i)
}

В условии появился один дополнительный знак — равно. Теперь True возвращается, если i меньше или равно 150. Поэтому вывод изменился. Конструкция отрабатывает и при i = 150.

Вы увидите такой результат:

100
110
120
130
140
150

Таких циклов ForClause можно придумать бесконечное количество. Например, вы можете выполнять итерацию в обратном порядке — от конца к началу. Для этого нужно изменить условие и постоператор.

for i := 50; i > 0; i -= 10 {
  fmt.Println(i)
}

Здесь отсчет начинается с i = 100. На каждой итерации происходит проверка, что i больше 0. Пока это условие выполняется, от текущего i вычитается 10. 

В итоге будет так:

50
40
30
20
10

Цифра 0 уже не выводится, потому что в условии указано, что i должно быть больше: i > 0.

Цикл с условием

Если вы уберете из синтаксиса инициирующий оператор и постоператор, то получите простую конструкцию с состоянием, при котором она работает. Объявление цикла в таком случае будет выглядеть так:

i := 0
for i < 6 {
    fmt.Println(i)
    i++
}

Если вы знакомы с другими языками программирования, то наверняка узнали в таком подходе работу while.

В этом примере вы определяете i за пределами конструкции. У синтаксиса for остается только требование — выполнять код, пока i меньше 6. Обратите внимание — та операция, которую вы указывали в качестве постоператора в предыдущих примерах (i++), теперь находится внутри тела.

В некоторых случаях количество итераций заранее неизвестно. Из-за этого вы не можете указать условие, при невыполнении которого loop будет завершен. Чтобы это не приводило к бесконечной работе, Go-циклы поддерживают ключевое слово break. Рассмотрим его работу на простом примере:

func main() {
    i := 0
    for {
        fmt.Println("Hello")
        if i == 5 {
            break
        }
        i++
    }
}

Сначала вы задаете i = 0. Затем запускаете loop, который каждый раз выводит приветствие. Это продолжалось бы бесконечно, если бы вы не задали условие прекращения работы. После пятой итерации, когда i станет равно 5, сработает break и программа остановится.

RangeClause

Для решения повторяющихся задач в Go есть еще один тип loop — RangeClause. Он очень похож на ForClause, но по умолчанию возвращает два значения: индекс элемента и значение элемента. 

Проще посмотреть на примере:

package main
import "fmt"
func main() {
    words := []string{"time", "web", "timeweb", "cloud"}
    for i, word := range words {
        fmt.Println(i, word)
    }
}

В консоли будет:

0 time
1 web
2 timeweb
3 cloud

Чтобы убрать индекс, используйте вместо i пустой идентификатор. Он обозначается символом нижнего подчеркивания:

package main
import "fmt"
func main() {
    words := []string{"time", "web", "timeweb", "cloud"}
    for _, word := range words {
        fmt.Println(word)
    }
}

В консоли отобразится:

time
web
timeweb
cloud

RangeClause также можно использовать для добавления элементов в список:

package main
import "fmt"
func main() {
    words := []string{"time", "web", "timeweb", "cloud"}

    for range words {
        words = append(words, "great")
    }

    fmt.Printf("%q\n", words)
}

Вы увидите:

["time" "web" "timeweb" "cloud" "great" "great" "great" "great"]

В этом примере вы добавили элемент "great" каждому элементу длины среза words.

Ещё одно применение range — заполнение среза значениями. Допустим, у вас есть срез, состоящий из 10 нулей. Необходимо заполнить его цифрами от 0 до 9. Код:

package main
import "fmt"
func main() {
    integers := make([]int, 10)
    fmt.Println(integers)

    for i := range integers {
        integers[i] = i
    }
    fmt.Println(integers)
}

Результат:

[0 0 0 0 0 0 0 0 0 0]
[0 1 2 3 4 5 6 7 8 9]

И еще один пример — использование range для получения доступа к каждому символу внутри строки:

package main
import "fmt"
func main() {
    timeweb := "Timeweb"

    for _, letter := range timeweb {
        fmt.Printf("%c\n", letter)
    }
}

Получится такой ответ:

T
i
m
e
w
e
b

Вложенные конструкции

Создать цикл for можно внутри другой конструкции. Тогда он станет вложенным. На псевдокоде его синтаксис можно представить следующим образом:

for {
    [Action]
    for {
        [Action]  
    }
}

Сначала запускается внешний loop. Он выполняется и запускает внутренний loop. После выполнения внутренней конструкции программа возвращается наверх. Процедура повторяется до тех пор, пока сохраняется заданное состояние или не срабатывает оператор break.

Здесь тоже существует опасность создать бесконечный круг, для работы которого не хватит даже мощностей timeweb.cloud — он просто никогда не завершится. Чтобы не допустить этого, не забывайте проверять состояние или используйте оператор break.

Проще всего понять концепцию вложенности на примере:

package main
import "fmt"
func main() {
    numList := []int{1, 2}
    alphaList := []string{"a", "b", "c"}
    for _, i := range numList {
        fmt.Println(i)
        for _, letter := range alphaList {
            fmt.Println(letter)
        }
    }
}

После выполнения этой программы вы получите:

1
a
b
c
2
a
b
c

Это отличная демонстрация порядка выполнения операций. Сначала выводится первое значение из первого списка — 1. Затем отрабатывает внутренняя конструкция, которая выводит содержимое строки "a", "b", "c". Затем программа возвращается в начало и снова выводит цифру из списка — на этот раз 2. Следующий шаг — повторная печать строки "a", "b", "c".

Заключение

Использовать циклы for просто. В зависимости от задачи вы можете выбрать один из трех вариантов или комбинировать их, создавая вложенные конструкции. Контролировать работу можно с помощью изменения состояния, инициирующего оператора и постоператора, а также добавления операторов break и continue.

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону