Как работает добавление элементов в слайс с помощью функции `append`?

Ответ

Добавление элементов в слайс происходит с помощью встроенной функции append. Механизм её работы зависит от ёмкости (capacity) слайса.

Слайс в Go — это структура, содержащая три поля:

  1. Указатель на базовый массив (underlying array).
  2. Длина (len) — количество элементов в слайсе.
  3. Ёмкость (cap) — количество элементов, которое может поместиться в базовом массиве, начиная с указателя.

Алгоритм append:


  1. Проверка ёмкости: Если текущая ёмкость (cap) больше длины (len), новый элемент добавляется в существующий базовый массив. Длина (len) слайса увеличивается.


  2. Переаллокация: Если ёмкости недостаточно (cap == len), создаётся новый базовый массив большего размера. Стандартная стратегия роста:

    • Для слайсов до 1024 элементов ёмкость удваивается.
    • Для слайсов больше 1024 элементов ёмкость увеличивается примерно в 1.25 раза.

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

Пример:

// Изначально len=3, cap=3
s := []int{1, 2, 3}

// cap > len, новый массив не нужен. len=4, cap=6 (произошла переаллокация)
s = append(s, 4)

// cap > len, новый массив не нужен. len=6, cap=6
s = append(s, 5, 6)

// cap == len, будет создан новый массив с большей ёмкостью
s = append(s, 7) // len=7, cap=12

Ключевые моменты:

  • append возвращает новый слайс. Его всегда нужно переприсваивать (slice = append(slice, elem)), так как базовый массив может измениться.
  • Для предсказуемой производительности можно заранее выделить ёмкость с помощью make([]T, len, cap).