Основы Go
2026-02-26 23:16 Diff

Срезы (slices) в Go передаются по значению, но содержат указатель на данные, поэтому простое присваивание приводит к совместному использованию одной и той же области памяти. Изменения в одном срезе могут повлиять на другой:

Чтобы избежать таких побочных эффектов, нужно явно копировать содержимое среза.

Копирование с помощью slices.Clone()

Стандартный пакет slices предлагает удобную функцию Clone(), которая создаёт новый срез с тем же содержимым, не изменяя оригинал:

Функция Clone всегда создаёт новый срез с собственной памятью.

Частичное копирование с помощью copy()

Если нужно скопировать данные из одного среза в другой, используйте функцию copy():

Копируется min(len(src), len(dst)) элементов.

Копирование с помощью append()

Ещё один способ безопасно скопировать срез — использовать append:

Создаётся новый срез, и содержимое копируется в него.

Почему простого присваивания недостаточно

Присваивание среза копирует только структуру (указатель, длину и ёмкость), но не сам массив. В результате оба среза указывают на один и тот же участок памяти:

Пример: безопасное клонирование перед модификацией

Рекомендации

  • Функция slices.Clone() удобна для создания независимой копии среза.
  • Используйте copy() или append() для ручного клонирования или переноса элементов.
  • Избегайте присваивания (b := a), если ожидается независимость данных.