Ответ
Длина и ёмкость — это две фундаментальные характеристики слайса в Go, которые часто вызывают путаницу у новичков.
Длина (Length) — это количество элементов, которые слайс содержит на данный момент. Это значение возвращается функцией
len(s)
. Вы можете получить доступ к элементам по индексу от0
доlen(s)-1
.Ёмкость (Capacity) — это количество элементов в базовом (скрытом) массиве, начиная с первого элемента слайса, которые могут быть использованы без необходимости нового выделения памяти. Это значение возвращается функцией
cap(s)
. Ёмкость определяет, до какого размера слайс может вырасти с помощьюappend
без реаллокации.
Всегда выполняется условие: 0 <= len(s) <= cap(s)
.
Пример создания и работы:
При создании слайса с помощью make
можно указать и длину, и ёмкость.
// Создаем слайс с длиной 3 и ёмкостью 5
s := make([]int, 3, 5)
fmt.Println(s) // Вывод: [0 0 0]
fmt.Println(len(s)) // Вывод: 3
fmt.Println(cap(s)) // Вывод: 5
В этом примере:
- Слайс
s
содержит 3 элемента (все инициализированы нулями). - Мы можем добавить еще
5 - 3 = 2
элемента с помощьюappend
без выделения новой памяти под базовый массив.
// Добавляем один элемент. Длина увеличивается, ёмкость та же.
s = append(s, 1)
fmt.Println(s) // Вывод: [0 0 0 1]
fmt.Println(len(s)) // Вывод: 4
fmt.Println(cap(s)) // Вывод: 5
// Добавляем еще один элемент. Длина достигает ёмкости.
s = append(s, 2)
fmt.Println(s) // Вывод: [0 0 0 1 2]
fmt.Println(len(s)) // Вывод: 5
fmt.Println(cap(s)) // Вывод: 5
// Добавляем еще один элемент. Происходит реаллокация.
// Go создает новый массив (обычно с удвоенной ёмкостью) и копирует туда старые элементы.
s = append(s, 3)
fmt.Println(s) // Вывод: [0 0 0 1 2 3]
fmt.Println(len(s)) // Вывод: 6
fmt.Println(cap(s)) // Вывод: 10 (или другое значение, зависит от стратегии роста)