Назад к вопросам
Senior
8
Как устроен слайс в Go? Расскажите о внутренней реализации, подводных камнях и нюансах.
Компании, где спрашивали
техвил
Ответ от нейросети
sobes.tech AI
Слайс в Go — это структура, которая описывает последовательный фрагмент массива. Внутренне слайс содержит три поля:
- ptr — указатель на первый элемент массива, к которому относится слайс (не обязательно на первый элемент всего массива, а на первый элемент слайса);
- len — длина слайса (количество элементов);
- cap — ёмкость слайса (максимальное количество элементов, которые можно вместить, начиная с ptr).
type sliceHeader struct {
ptr *ElementType
len int
cap int
}
Нюансы и подводные камни:
- При создании слайса из массива или другого слайса, новый слайс ссылается на тот же underlying array. Изменения через один слайс отражаются в другом.
- Если слайс увеличить по длине (через append), и ёмкости не хватает, создаётся новый массив, и данные копируются туда.
- Из-за совместного использования массива может возникнуть утечка памяти: если слайс ссылается на большой массив, но используется только маленькая часть, весь массив не будет освобождён.
- При передаче слайса в функцию копируется структура слайса (ptr, len, cap), но не копируются данные массива.
Пример:
arr := [5]int{1,2,3,4,5}
s1 := arr[1:3] // слайс с элементами {2,3}
s2 := s1[:4] // расширяем длину до 4, но не больше cap
s2[3] = 10 // меняем элемент в исходном массиве
fmt.Println(arr) // [1 2 3 10 5]
Важно понимать, что слайсы — это удобный и эффективный способ работы с последовательностями, но нужно внимательно следить за их ёмкостью и временем жизни underlying array, чтобы избежать неожиданных ошибок и утечек памяти.