Назад к вопросам
Junior
168
questionbank
Как можно нарезать слайс в Go? Какие нюансы и подводные камни могут возникнуть?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Нарезка слайса в Go достигается с помощью синтаксиса a[low:high], где low — начальный индекс (включительно), а high — конечный индекс (не включительно). Также доступны варианты a[:high] (от начала до high), a[low:] (от low до конца) и a[:] (копия всего слайса).
Нюансы и подводные камни:
- Общий базовый массив: Нарезка слайса создает новый слайс, который делит базовый массив с исходным слайсом. Изменения в элементах одного слайса отразятся в другом (если они ссылаются на один и тот же базовый массив).
- Изменение capacity: Новый слайс имеет ту же capacity, что и исходный, уменьшенную на
low. Это может привести к неожиданным изменениям при добавлении элементов (append) в нарезанный слайс, если его capacity будет исчерпана раньше capacity исходного слайса. - Выход за границы: Индексы
lowиhighдолжны быть в пределах [0, len(a)] и [0, cap(a)] соответственно. Нарушение этих правил приведет к панике во время выполнения:panic: slice bounds out of range. - Создание независимой копии: Чтобы создать независимую копию слайса, необходимо использовать функцию
copy.
Примеры:
// Исходный слайс
s := []int{1, 2, 3, 4, 5}
// Нарезка от индекса 1 до 3 (не включая 3)
s1 := s[1:3] // s1 будет {2, 3}
// Нарезка от начала до индекса 3
s2 := s[:3] // s2 будет {1, 2, 3}
// Нарезка от индекса 2 до конца
s3 := s[2:] // s3 будет {3, 4, 5}
// Копия всего слайса
s4 := s[:] // s4 будет {1, 2, 3, 4, 5}
// Демонстрация общего базового массива
s1[0] = 100 // Изменение в s1
// Теперь s имеет вид {1, 100, 3, 4, 5}
// Создание независимой копии
s5 := make([]int, len(s))
copy(s5, s) // s5 теперь {1, 100, 3, 4, 5}
// Изменение в s5 не повлияет на s
s5[0] = 200
// s останется {1, 100, 3, 4, 5}
// s5 теперь {200, 100, 3, 4, 5}
Таблица, иллюстрирующая cap нарезанных слайсов:
Исходный слайс s |
len(s) |
cap(s) |
Нарезка | Результат | len нарезанного |
cap нарезанного |
|---|---|---|---|---|---|---|
{1, 2, 3, 4, 5} |
5 | 5 | s[1:3] |
{2, 3} |
2 | 4 |
{1, 2, 3, 4, 5} |
5 | 5 | s[:3] |
{1, 2, 3} |
3 | 5 |
{1, 2, 3, 4, 5} |
5 | 5 | s[2:] |
{3, 4, 5} |
3 | 3 |
{1, 2, 3, 4, 5} |
5 | 5 | s[:] |
{1, 2, 3, 4, 5} |
5 | 5 |
Понимание работы с базовым массивом и capacity является ключевым для эффективной работы со слайсами в Go и избежания unexpected results.