массивы (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
).