range по числу
Пока бегун сам считает круги, он может сбиться: начать счёт не с того числа или пробежать лишний круг. На многих стадионах круги считает табло, и бегуну остаётся только бежать.
Цикл с тремя частями — это бегун, который считает сам. Чтобы повторить действие n раз, он держит счётчик, условие и шаг. Это три места, где можно ошибиться:
- начать с единицы вместо нуля;
- поставить
<=вместо<; - забыть шаг.
Для такого повтора в Go есть короткая запись с ключевым словом range — это и есть табло:
package main
import "fmt"
func main() {
for i := range 5 {
fmt.Print(i, " ") // 0 1 2 3 4
}
}Давайте посмотрим, что напечатала программа. Тело выполнилось пять раз, а i по очереди было 0, 1, 2, 3 и 4.
Две формы range по числу
У этой записи две формы: с переменной для номера итерации и без неё.
С переменной: for i := range n
Заголовок читается слева направо:
for— ключевое слово цикла;i :=объявляет переменную для номера итерации;range nговорит, сколько итераций выполнить.
Цикл выполняет n итераций, а переменная i по очереди принимает значения от 0 до n - 1. Он делает то же, что for i := 0; i < n; i++, но Go сам ведёт счётчик и шаг. Значения 5 переменная i не принимает: последняя итерация идёт с i, равной 4.
Здесь табло отличается от настоящего: оно начинает счёт с нуля. Человек назовёт первый круг первым, а range — нулевым. Об этом стоит помнить каждый раз, когда номер итерации попадает в вычисления.
Вместо числа можно написать переменную или выражение типа int:
for i := range countвыполняет телоcountраз;- если значение равно нулю или отрицательное, тело не выполняется ни разу;
- когда счёт идёт не с нуля или в обратную сторону, нужен цикл с тремя частями, например
for i := 5; i >= 1; i--.
Без переменной: for range n
Когда номер итерации не нужен, переменную не объявляют вовсе. Запись for range 3 выполняет тело три раза:
for range 3 {
fmt.Print("Go ") // Go Go Go
}Объявить i и не использовать её нельзя: неиспользуемая переменная — ошибка компиляции, и для цикла правило то же. Поэтому для повтора без номера пишут for range n без имени.
Инструкции break и continue работают в обеих формах так же, как в цикле с тремя частями.
Что изменилось в Go 1.22
Эта запись появилась в Go 1.22, поэтому в старых учебниках её нет. В той же версии изменились два правила:
- появился
rangeпо целому числу; - каждая итерация любого цикла
forполучает собственную копию переменной цикла.
В программах этой темы разницы во втором правиле не видно, но об этом изменении часто спрашивают на собеседованиях.
Частая ошибка
Цикл по range 5 должен сложить числа от 1 до 5:
s := 0
for i := range 5 { // ✗
s += i
}
fmt.Println(s)Программа печатает 10, а не 15: переменная i пробегает значения от 0 до 4, и пятёрка в сумму не попадает. Прибавляйте i + 1 или запишите цикл с тремя частями: for i := 1; i <= 5; i++.
Главное
for i := range nвыполняетnитераций, иiпринимает значения от0доn - 1.- При нулевом или отрицательном
nтело не выполняется ни разу. for range nповторяет телоnраз без переменной.- Для счёта не с нуля или в обратную сторону нужен цикл с тремя частями.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.