Особенности массивов в Go и их ключевые отличия от срезов (slices)?

Ответ

Массив в Go — это нумерованная последовательность элементов одного типа с фиксированной длиной, которая является частью его типа.

Ключевые особенности массива:

  • Фиксированный размер: Длина массива определяется при его создании и не может быть изменена. Размер является частью типа ([3]int и [5]int — это разные, несовместимые типы).
  • Тип-значение (Value Type): При присваивании или передаче в функцию создается полная копия массива. Это может быть неэффективно для больших массивов.
  • Инициализация: Элементы, которым не присвоено значение при инициализации, получают нулевое значение для своего типа (0 для чисел, false для bool, "" для строк и т.д.).

Ключевые отличия от срезов:

ХарактеристикаМассив ([N]T)Срез ([]T)
РазмерФиксированный, определяется при компиляцииДинамический, может изменяться во время выполнения
Передача в функциюПо значению (копируется весь массив)По значению (копируется структура среза, а не данные)
ГибкостьНизкаяВысокая (можно добавлять элементы, изменять размер)
ПроизводительностьДоступ к элементам очень быстрый. Копирование может быть медленным.Доступ быстрый. Рост может вызвать переаллокацию памяти.

Пример:

// Массив: длина 3, является частью типа [3]int
var a [3]int          // [0 0 0]
b := [3]int{1, 2}     // [1 2 0] - последний элемент инициализирован нулем

// Срез: длина динамическая
c := []int{1, 2}      // Срез длиной 2
c = append(c, 3)      // Теперь срез [1 2 3]

Вывод: В большинстве случаев для работы с коллекциями в Go следует предпочитать срезы из-за их гибкости и эффективности при передаче в функции.