← Назад к вопросам

Когда используется массив?

1.8 Middle🔥 191 комментариев
#Другое#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда использовать массивы в Go

В Go массив — это структура данных фиксированного размера, состоящая из последовательности элементов одного типа. Хотя в современной Go-разработке срезы (slices) используются гораздо чаще, массивы имеют свои конкретные ниши применения.

Ключевые характеристики массивов

  • Фиксированный размер: длина массива является частью его типа и задаётся при объявлении. Например, [5]int и [10]int — это разные типы.
  • Значимый тип: массивы передаются по значению — при присваивании или передаче в функцию копируется весь массив.
  • Память на стеке: массив обычно размещается в стеке, если его размер известен на этапе компиляции и не слишком велик.

Основные случаи использования массивов

1. Когда важен фиксированный размер и безопасность

Массивы гарантируют, что структура данных никогда не изменит свой размер, что исключает случайное перераспределение памяти.

// Конфигурация с фиксированным количеством параметров
type Config struct {
    Keys [4]string  // Всегда ровно 4 ключа
    Values [4]int
}

2. Для оптимизации производительности

Поскольку массивы размещаются в стеке и не требуют выделения памяти в куче, они могут быть более эффективными для небольших коллекций фиксированного размера.

// Матрица 3x3 для математических вычислений
type Matrix3x3 [3][3]float64

func (m Matrix3x3) Multiply(other Matrix3x3) Matrix3x3 {
    var result Matrix3x3
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            for k := 0; k < 3; k++ {
                result[i][j] += m[i][k] * other[k][j]
            }
        }
    }
    return result
}

3. При работе с низкоуровневыми или системными API

Некоторые системные вызовы и библиотеки (например, криптографические функции) ожидают массивы фиксированного размера.

// Работа с SHA-256 хэшем (всегда 32 байта)
func computeHash(data []byte) [32]byte {
    return sha256.Sum256(data)
}

// Сравнение хэшей - массивы сравниваются поэлементно
func hashesEqual(h1, h2 [32]byte) bool {
    return h1 == h2  // Возможность сравнения целиком!
}

4. Для создания константных коллекций

В Go можно создавать константные массивы, используя ключевое слово const.

const daysOfWeek = [7]string{
    "Monday",
    "Tuesday", 
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday",
}

5. Когда семантика значения важнее ссылки

Поскольку массивы копируются целиком, они обеспечивают "value semantics" — независимость копий данных.

// Координаты в 3D пространстве
type Point3D [3]float64

func translate(p Point3D, dx, dy, dz float64) Point3D {
    return Point3D{p[0] + dx, p[1] + dy, p[2] + dz}
    // Исходная точка не изменяется
}

6. Для статических таблиц и lookup-массивов

Таблицы поиска с предвычисленными значениями часто удобно хранить в массивах.

// Таблица синусов для предвычисленных значений
var sinTable [360]float64

func init() {
    for i := 0; i < 360; i++ {
        sinTable[i] = math.Sin(float64(i) * math.Pi / 180)
    }
}

Важные различия между массивами и срезами

// Массив - значимый тип
arr := [3]int{1, 2, 3}
arrCopy := arr  // Полное копирование всех элементов
arrCopy[0] = 99 // Не влияет на arr

// Срез - ссылочный тип
slice := []int{1, 2, 3}
sliceCopy := slice  // Копируется только заголовок среза
sliceCopy[0] = 99   // Изменяет исходный срез тоже!

Практические рекомендации

  • Используйте массивы когда:

    • Размер коллекции известен на этапе компиляции и не изменится
    • Нужна семантика значений (полное копирование)
    • Работаете с небольшими коллекциями (до ~1KB)
    • Требуется максимальная производительность для критичных участков кода
  • Предпочитайте срезы когда:

    • Разколлекции динамический или неизвестен заранее
    • Работаете с большими наборами данных
    • Нужна гибкость (добавление/удаление элементов)
    • В большинстве обычных сценариев разработки

Массивы в Go — это специализированный инструмент с четкой областью применения. Они обеспечивают предсказуемость по памяти, безопасность типов (фиксированный размер) и могут быть полезны для оптимизации. Однако для большинства повседневных задач срезы остаются более удобным и гибким выбором благодаря своей динамической природе и тесной интеграции с остальными частями стандартной библиотеки Go.

Когда используется массив? | PrepBro