Урок 1 из 118

Массивы: длина — часть типа

Сергей выдал Мише первую задачу — импорт каталога для «Полки». Миша завёл под запись массив из пяти полей.

Go

К вечеру функция, написанная под пять полей, отказалась принимать шесть — хорошо, что компилятор ее не собрал и проблем в проде удалось избежать.

Output
cannot use fields6 (variable of type [6]string) as [5]string value in argument to importOperation
Главная мысль

Массив — это N значений одного типа, и N входит в тип на этапе компиляции: [3]int и [4]int — разные типы; массив копируется целиком (по семантике), а место массивов в реальном коде — буферы.

Почему так произошло?

Если рассматривать массив с точки зрения памяти, то его длина будет являться частью типа, которая устанавливается при компиляции приложения.

Таким образом [3]int и [4]int будут двумя разными типами, как int и string.

Типичные ошибки

Нельзя объявить параметр вида [N]int, который работал бы с длиной M — для каждой длины свой тип.

Так как длина — часть типа, то компилятору не нужно смотреть на данные: размер массива считается как длина × размер элемента.

Выберите тип элемента T — карточки пересчитаются, а ниже появится пояснение про байты.

Массив — это значение, а не ссылка на данные

Важно

При присваивании или передаче в функцию копируется весь массив, со всеми элементами.

Запустите код ниже в пошаговом режиме и посмотрите как изменяется память на каждом шаге выполнения программы.

Go

Каждый вызов copyArray получает собственную копию массива. В этом примере мы сохраняем адрес каждой копии, поэтому она остаётся в куче — на диаграмме видно, как память растёт примерно на 1 МБ за вызов.

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

Сравнение

Массивы сравниваются через == поэлементно, если их элементы сравнимы. Это отличает их от слайсов, которые сравнивать нельзя.

Go

Где массивы живут в реальном коде

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

В следующем уроке

Вы узнаете:

  • что такое arr[:] и как это связано со слайсом
  • как [...]int{1,2,3} сам считает длину
Задание · вопросы

Проверьте себя

Вопрос 1 из 2

Импорт каталога: Миша объявил хранилище [3]int, а сервис вернул пачку по четыре поля. Что произойдёт при var a [3]int; var b [4]int; a = b?

Вопрос 2 из 2

«Полка» сверяет дубликаты каталога через ==. Массивы a := [2]int{1, 2} и b := [2]int{2, 1}. a == b?

Итоги

Длина массива — это часть типа, по семантике языка массив копируется целиком.
Массивы можно сравнивать через ==. В прикладном коде — массив часто является буфером фиксированного размера.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки