Границы массивов и итерация

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. Ключевые выводы

  1. Границы массива: Всегда проверяйте i < len(array) во избежание panic
  2. len(array) — надёжный способ получить границу цикла
  3. for range — идиоматичный способ перебора в Go, безопаснее классического for
  4. Типы данных: При вычислениях с дробными результатами используйте float64 и приведение типов
  5. _ (пустой идентификатор) — для игнорирования ненужных значений (индекс или элемент)

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  // Без второй переменной