Назад к вопросам
Junior
213
questionbank
Как работают слайсы в Go?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Слайс — это легкая оболочка над массивом. Он не хранит данные сам по себе, а ссылается на базовый массив.
Структура слайса:
- Указатель на базовый массив: Адрес первого элемента слайса в памяти.
- Длина (Length): Количество элементов в слайсе.
- Емкость (Capacity): Количество элементов в базовом массиве, доступных начиная с указателя слайса.
// Пример объявления слайса
var s []int
s = append(s, 1, 2, 3) // Добавление элементов
// Внутреннее представление слайса s (упрощенно)
// struct SliceHeader {
// Data uintptr // Указатель на базовый массив
// Len int // Длина слайса
// Cap int // Емкость слайса
// }
- При создании слайса с помощью
make([]T, length, capacity)создается базовый массив указанной емкости и слайс, ссылающийся на него с указанной длиной. - При использовании среза на массиве или другом слайсе (например,
arr[low:high:max]) создается новый слайс, который ссылается на ту же область памяти базового массива, но с другими указателем, длиной и емкостью. - Операция
appendможет привести к перевыделению памяти. Если текущая емкость недостаточна для добавления новых элементов, Go создает новый, больший базовый массив, копирует в него элементы старого массива и обновляет указатель слайса на новый массив. Это называется реаллокацией. Алгоритм роста емкости при аппенде экспоненциальный (удваивается до определенного размера, затем рост замедляется). - Слайсы передаются по значению, но так как они содержат указатель на базовый массив, изменения элементов слайса (через индекс) будут видны во всех слайсах, ссылающихся на тот же базовый массив.
- Изменение длины слайса через срез не затрагивает базовый массив, но может ограничить доступ к части данных базового массива.
Таблица: Сравнение Length и Capacity
| Характеристика | Длина (Length) | Емкость (Capacity) |
|---|---|---|
| Определение | Фактическое количество элементов в слайсе | Максимальное количество элементов, которые могут быть в слайсе без перевыделения |
| Доступ | Используется для доступа к элементам (s[i]) | Определяет, сколько еще элементов можно добавить через append до реаллокации |
| Получение | len(s) |
cap(s) |
// Пример работы с емкостью и длиной
s := make([]int, 0, 5) // Длина 0, емкость 5
fmt.Println(len(s), cap(s)) // 0 5
s = append(s, 1, 2) // Добавляем 2 элемента
fmt.Println(len(s), cap(s)) // 2 5
s = append(s, 3, 4, 5, 6) // Добавляем еще 4 элемента, нужна реаллокация
fmt.Println(len(s), cap(s)) // 6 10 (емкость увеличилась)