Как в Go перебрать диапазон целых чисел от A до B без создания слайса?
Классический цикл for: ваш главный инструмент
Да, вы правы: в Go нет встроенной функции range() как в Python. Но это не недостаток, а особенность дизайна языка. Go предпочитает явность и простоту. Классический цикл for — это основной и самый идиоматичный способ перебора чисел.
Ваш пример for i := 0; i < 100; i++ — абсолютно правильный и широко используемый код. Он не многословен, а явен: вы сразу видите начальное значение, условие продолжения и шаг. Это повышает читаемость, особенно в сложных алгоритмах.
Перебор в обратном порядке и с шагом
Для перебора от 100 до 1 с шагом 2:
for i := 100; i >= 1; i -= 2 {
fmt.Println(i)
}
Перебор от A до B
Для диапазона от 5 до 15:
for i := 5; i <= 15; i++ {
fmt.Println(i)
}
Новое в Go 1.22: range над целыми числами
Начиная с Go 1.22 (вышел в феврале 2024 года), появилась возможность использовать range с целым числом! Теперь ваш первый пример будет работать:
for i := range 100 {
fmt.Println(i) // выведет 0, 1, 2, ..., 99
}
Важно: range 100 перебирает числа от 0 до 99 (не включая 100), аналогично for i := 0; i < 100; i++. Это удобно, когда нужно просто выполнить действие N раз или перебрать индексы от 0 до N-1.
А как же диапазон от A до B?
Прямой поддержки range(5, 15) в Go нет и не планируется. Но вы можете использовать небольшие вспомогательные функции:
package main
import "fmt"
// Range возвращает слайс чисел от start до end (не включая end)
func Range(start, end int) []int {
if start > end {
return nil
}
result := make([]int, end-start)
for i := start; i < end; i++ {
result[i-start] = i
}
return result
}
func main() {
for _, i := range Range(5, 15) {
fmt.Println(i) // 5, 6, ..., 14
}
}
Но! В Go принято избегать создания слайсов без необходимости. Лучше использовать классический for — он не выделяет память и работает быстрее.
Идиоматичный подход в Go
Вместо того чтобы искать аналог Python-функции range, привыкайте к явному циклу for. Это стандарт Go, который используют все опытные разработчики. Вот несколько примеров:
- Повторить действие N раз:
for i := 0; i < N; i++ { ... } - Перебор с конца:
for i := N-1; i >= 0; i-- { ... } - Бесконечный цикл:
for { ... } - Цикл с условием:
for i < 10 { ... }(как while в других языках)
Примите эту особенность Go — она делает код предсказуемым и эффективным. А если вам очень не хватает Python-стиля, используйте range N из Go 1.22 для простых случаев.
Альтернатива: итераторы и функциональный подход
Если вы хотите более выразительный код и не боитесь небольших накладных расходов на производительность, можно создать функцию-генератор, возвращающую итератор. Начиная с Go 1.23 (ожидается в 2024 году), в язык будут добавлены встроенные итераторы (iterators). Но уже сейчас можно использовать простой паттерн с замыканиями:
func rangeInt(start, end int) func() (int, bool) {
i := start
return func() (int, bool) {
if i >= end {
return 0, false
}
val := i
i++
return val, true
}
}
func main() {
next := rangeInt(5, 15)
for {
val, ok := next()
if !ok {
break
}
fmt.Println(val)
}
}
Этот подход более гибкий: вы можете легко изменить шаг или добавить фильтрацию. Однако для простых задач классический for остаётся лучшим выбором. Помните: в Go простота и производительность важнее синтаксического сахара.
Ответов пока нет.
Войдите чтобы оставить ответ