5 вопросов
Циклы for и range - единственная конструкция итерации в Go. Range работает со слайсами, map, каналами, строками и целыми числами (Go 1.22+). Понимание тонкостей копирования элементов и вычисления длины критически важно.
s := []int{1, 2, 3}; for range s { s = append(s, 1) }? 🟡 Средний
▶
range вычисляет длину слайса один раз при входе в цикл. Последующие append не увеличивают количество итераций, хотя сам слайс растёт. Цикл выполнится ровно 3 раза (по исходной длине).
Подробнее →for i := range 5 { fmt.Print(i) } (Go 1.22+)? 🟡 Средний
▶
Начиная с Go 1.22, range может принимать целое число. for i := range N итерирует от 0 до N-1. Это упрощает запись циклов, аналогично range(N) в Python.
items := []struct{X int}{{1},{2}}; for _, v := range items { v.X = 0 }; fmt.Println(items[0].X)? 🟡 Средний
▶
В for range переменная v - это копия элемента, а не ссылка на него. Изменение v.X меняет копию, оригинальный слайс остаётся нетронутым. Чтобы менять элементы, нужно итерировать по индексу: items[i].X = 0.
Подробнее →for цикла, содержащего select, при получении сигнала из канала done? 🔴 Сложный
▶
Простой break внутри select выходит только из select, а не из for. Для выхода из внешнего цикла нужен labeled break: Loop: for { select { case <-done: break Loop } }. break без метки в select бесполезен для выхода из for.
Подробнее →Go 1.23 позволяет использовать функции-итераторы в for range. Функция вызывает yield для каждого элемента. Если yield вернул false - итерация прекращена (break). Пакеты slices.All, maps.Keys, maps.Values возвращают такие итераторы.
Подробнее →