Слайсы
Динамические коллекции данных в 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+ элементов) для понимания реального поведения.