Этот вопрос проверяет понимание внутренней структуры срезов в Go и их аллокации.
Массив — это непрерывный блок памяти фиксированного размера [N]T. Срез ([]T) представлен тройкой: указатель на начало массива, длина (len) и ёмкость (cap) — максимальное число элементов до перевыделения. capacity показывает, сколько элементов можно поместить срезу без выделения нового массива при append.
Массив:
Стек или куча, размер N * sizeof(T).
Срез (Slice):
ptr: указатель на первый элемент
len: текущее число элементов
cap: число элементов от ptr до конца базового массива
Append и capacity:
При append(slice, elem) если len < cap, пишем в базовый массив.
Если len == cap, создаётся новый массив удвоенного размера и копируется содержимое.
Пример:
a := make([]int, 0, 5)
fmt.Println(len(a), cap(a)) // 0 5
a = append(a, 1,2,3)
fmt.Println(len(a), cap(a)) // 3 5Вывод:
Cap позволяет снизить количество аллокаций при сборе динамических данных.