массивы (arrays) и срезы (slices)

В Go массивы (arrays) и срезы (slices) — это разные структуры данных, а len и cap — функции, которые работают со срезами (и массивами, но для массивов они всегда равны).

🔹 Массив vs Срез

Характеристика Массив ([n]T) Срез ([]T)
Размер Фиксированный (известен на этапе компиляции) Динамический (может расти и уменьшаться)
Передача в функцию По значению (копируется) По ссылке (указатель на массив)
Инициализация arr := [3]int{1, 2, 3} sl := []int{1, 2, 3} или make([]int, len, cap)
Гибкость Неизменяемый размер Можно изменять с помощью append

Примеры:

// Массив (фиксированная длина)
arr := [3]int{1, 2, 3}  // len=3, cap=3 (для массива len == cap)

// Срез (динамическая длина)
sl := []int{1, 2, 3}    // len=3, cap=3
sl = append(sl, 4)      // len=4, cap=6 (удвоился)

🔹 len vs cap

Обе функции применяются к срезам (и массивам), но имеют разный смысл:

  • len(s) — текущее количество элементов в срезе.
  • cap(s) — максимальное количество элементов, которое может вместить базовый массив без переаллокации.

Пример:

sl := make([]int, 2, 5)  // len=2, cap=5
fmt.Println(len(sl))     // 2 (элементы: [0, 0])
fmt.Println(cap(sl))     // 5 (может вместить ещё 3 элемента)

sl = append(sl, 1, 2, 3) // len=5, cap=5
sl = append(sl, 4)       // len=6, cap=10 (удваивается при переполнении)

Вывод:

  • Массивы — статические, срезы — динамические.
  • len — текущая длина, cap — ёмкость внутреннего массива.
  • append может увеличить len, а если места нет (len == cap), то Go выделит новый массив (обычно с удвоенной cap).