Назад к вопросам
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.