Основы Go
2026-02-26 17:24 Diff

Срезы в Go — это лёгкие структуры, содержащие указатель на базовый массив, длину (len) и вместимость (cap). При передаче в функцию срез копируется как структура, но оба среза продолжают указывать на один и тот же массив. Это поведение важно для понимания того, когда изменения внутри функции отражаются на исходных данных, а когда нет.

Передача срезов

При передаче среза в функцию изменения элементов видны снаружи, потому что копируется только структура, а не массив.

Здесь функция modify() изменила первый элемент, и изменение видно в main().

Вызов append() внутри функции

При использовании append() поведение зависит от вместимости исходного среза:

  • Если append() помещается в существующий массив, изменения видны снаружи.
  • Если append() создаёт новый массив (переполнена cap), изменения не будут видны, если не вернуть новый срез.

Чтобы изменения сохранились, возвращаем срез из функции:

Возврат срезов

Возвращение срезов из функций безопасно: копируется только структура, а массив остаётся в памяти столько, сколько нужен.

Под-срезы и утечки памяти

Если взять под-срез большого массива, он продолжит удерживать в памяти весь массив, даже если используется только часть данных.

Чтобы освободить неиспользуемую память, можно сделать копию:

Вывод

  • Срезы передаются по значению, но содержат указатель на общий массив.
  • Изменения элементов внутри функции видны снаружи.
  • При использовании append() новый срез может указывать на другой массив — его нужно возвращать.
  • Возврат срезов безопасен, но под-срезы больших массивов могут удерживать память, которую стоит освобождать через копирование.
  • Чтобы избежать утечки памяти, скопируйте нужную часть среза, например через slices.Clone().