Слайсы

Динамические коллекции данных в Go: создание, изменение размера, внутреннее устройство и операции.

Что изучим

  • Отличия слайсов от массивов
  • Nil-слайс и пустой слайс
  • Внутренняя структура: указатель, длина, ёмкость
  • Создание через литералы и функцию make
  • Операция slicing для извлечения подмножества
  • Функция append и механизм роста ёмкости
  • Копирование слайсов и ссылочная семантика

Основные концепции

Слайс: динамическая обёртка над массивом. Объявляется без указания размера: []тип. Может изменять размер через append, в отличие от массивов с фиксированной длиной. Ссылочный тип — копирование передаёт указатель, а не данные.

Nil-слайс vs пустой слайс: неинициализированная переменная var s []int равна nil с длиной 0. Пустой слайс s := []int{} или make([]int, 0) не равен nil, но также имеет длину 0. Визуально одинаковы, семантически различны.

Внутренняя структура: слайс состоит из трёх компонентов — указателя на базовый массив, длины (количество элементов) и ёмкости (размер базового массива). Функции len() и cap() возвращают эти значения.

Функция make: создаёт слайс с заданной длиной и ёмкостью. Синтаксис make([]тип, длина) или make([]тип, длина, ёмкость). Заполняет слайс нулевыми значениями. Полезна для предварительного выделения памяти.

Slicing: операция извлечения подмножества arr[start:end]. Создаёт новый слайс, указывающий на те же данные. Ёмкость считается от начала среза до конца базового массива. Формула: cap = len(базовый_массив) - start_индекс.

Функция append: добавляет элементы в конец слайса. Результат всегда нужно присваивать обратно. При len == cap создаёт новый массив с увеличенной ёмкостью. Стратегия роста: удвоение для малых слайсов (cap < 256), увеличение на ~25% для больших.

Оптимизация производительности: если известно примерное количество элементов, используйте make([]тип, 0, ёмкость) для предотвращения множественных перевыделений памяти. Тестируйте рост на больших объёмах данных (500k+ элементов) для понимания реального поведения.