Границы массивов и итерация
1. Выход за границы массива (Index Out of Range)
Основное правило
- Нельзя обращаться к индексу за пределами массива (в положительную или отрицательную сторону)
- Попытка доступа к несуществующему индексу →
panic: runtime error: index out of range
Пример
numbers := [3]int{10, 20, 30}
fmt.Printf("Длина: %d\n", len(numbers))
// Допустимые индексы: 0, 1, 2
// ❌ ОШИБКА в runtime:
// fmt.Println(numbers[3])
// panic: runtime error: index out of range [3] with length 3
Важно: Ошибка не обнаруживается на этапе компиляции, только во время выполнения программы.
2. Итерация по массиву: классический for
Синтаксис
for i := 0; i < len(array); i++ {
// array[i] — доступ к элементу по индексу
}
Пример: подсчёт среднего арифметического
scores := [5]int{85, 92, 78, 90, 88}
sum := 0
for i := 0; i < len(scores); i++ {
sum += scores[i]
}
average := sum / len(scores)
fmt.Printf("Среднее: %d\n", average) // 86
3. Работа с типами при вычислении среднего
Проблема с целыми числами
scores := [5]int{85, 92, 78, 90, 88}
average := sum / len(scores) // Целочисленное деление → 86
Решение: вещественные числа
scores := [5]float64{85, 92, 78, 90, 88}
sum := 0.0
for i := 0; i < len(scores); i++ {
sum += scores[i]
}
average := sum / float64(len(scores)) // Приведение типа!
fmt.Printf("Среднее: %.2f\n", average) // 86.60
Критично: При делении нужно приводить len() к float64, иначе произойдёт целочисленное деление.
4. Итерация: for range
Полный синтаксис (индекс + значение)
colors := [4]string{"Red", "Green", "Blue", "Yellow"}
for index, value := range colors {
fmt.Printf("[%d] = %s\n", index, value)
}
Вывод:
[0] = Red
[1] = Green
[2] = Blue
[3] = Yellow
Только значения (игнорирование индекса)
for _, value := range colors {
fmt.Printf("%s\n", value)
}
Использование _ — пустой идентификатор для игнорирования ненужной переменной.
Только индексы (игнорирование значений)
for index := range colors {
fmt.Printf("Индекс: %d\n", index)
}
Синтаксис отличается: достаточно указать одну переменную без _.
5. Сравнение способов итерации
| Способ | Когда использовать | Синтаксис |
|---|---|---|
Классический for |
Нужен контроль над счётчиком, модификация массива по индексу | for i := 0; i < len(arr); i++ |
for range (индекс + значение) |
Нужны и индекс, и значение | for i, v := range arr |
for range (только значения) |
Индекс не нужен, только чтение | for _, v := range arr |
for range (только индексы) |
Нужны только позиции элементов | for i := range arr |
6. Ключевые выводы
- Границы массива: Всегда проверяйте
i < len(array)во избежаниеpanic len(array)— надёжный способ получить границу циклаfor range— идиоматичный способ перебора в Go, безопаснее классическогоfor- Типы данных: При вычислениях с дробными результатами используйте
float64и приведение типов _(пустой идентификатор) — для игнорирования ненужных значений (индекс или элемент)
7. Типичные ошибки
❌ Выход за границы:
arr := [3]int{1, 2, 3}
fmt.Println(arr[3]) // panic!
❌ Целочисленное деление вместо вещественного:
average := sum / len(scores) // int / int → int
✅ Правильно:
average := float64(sum) / float64(len(scores))
❌ Неправильное игнорирование в for range:
for index, _ := range arr // Можно, но избыточно
✅ Правильно:
for index := range arr // Без второй переменной