ПрограммированиеBackend разработчик

Расскажите, как Go реализует работу с памятью при передаче map и slice в функции, и чем это может быть чревато?

Проходите собеседования с ИИ помощником Hintsage

Ответ.

В Go структура map всегда передаётся по значению, но это значение содержит указатель на внутренние структуры самого map (под капотом — хэш-таблица). Поэтому если вы передаёте map в функцию и внутри функции меняете содержимое (добавляете/удаляете элементы), изменения будут видны снаружи. Аналогично ведут себя и slice — копируется структура slice, но не сам массив-данные: slice содержит указатель на массив, длину и ёмкость. Если изменять значения по индексу внутри функции, исходный массив тоже изменится. Но если из функции вы присваиваете новый slice (например, reslice), исходная переменная не изменится.

func updateMap(m map[string]int) { m["key"] = 42 // Изменения видны снаружи! } func updateSlice(s []int) { s[0] = 99 // Изменяется исходный массив }

Вопрос с подвохом.

Почему при передачи map и slice в функцию их изменение внутри функции отражается на "оригинале"?

Ответ: Потому что копируется только структура указателя, а сами данные остаются общими — любые изменения затрагивают один и тот же блок памяти.

Примеры реальных ошибок из-за незнания тонкостей темы.


История

В fintech проекте передавали map с настройками конфигурации в разные сервисы, предполагая, что локальные изменения не повлияют на общий map. В результате один сервис изменил значения, и это вызвало баги в других модулях, которые получили неожиданно изменённую конфигурацию.


История

В микросервисе аналитики передавали slice, рассчитывая получить независимые копии. Но функция внутри изменила значения по индексу, что привело к искажённым данным в отчёте, так как исходный массив был неожиданно изменён.


История

В игровых серверах использовали map для хранения сессий пользователей и параллельно передавали этот map в несколько горутин. Предполагалось, что каждая горутина работает со своей копией, но фактически возникла гонка данных и частично потерянные сессии.