В Go большинство встроенных типов данных (например, int, float, struct) — изменяемые, если они объявлены как переменные, потому что при передаче по значению копируется вся структура или значение. Но есть тонкость: срезы (slice), карты (map), каналы (channel) — ссылочные типы со своей внутренней логикой хранения данных.
Базовые типы:
x := 10 y := x // Здесь создается копия значения, x и y не связаны между собой y = 20 // x останется 10
Срезы:
a := []int{1,2,3} b := a // ссылка на ту же базовую «подложку» массива b[0] = 100 // теперь и a[0] == 100
Это важно, если функция или метод принимает структуру или срез, потому что изменения могут либо затронуть оригинальные данные, либо нет, в зависимости от типа данных и способа передачи (по значению или по ссылке).
Вопрос: "Если вы присваиваете один срез другому, получаете ли вы глубокую копию или оба указывают на одни и те же данные?"
Ответ: При простом присваивании срезов (b := a) — оба указывают на один и тот же базовый массив, но имеют независимые длину и ёмкость. Изменение через один из срезов данных самого массива видно в другом.
Пример:
a := []int{1,2,3} b := a b[0] = 42 fmt.Println(a) // [42 2 3]
Чтобы сделать глубокую копию, используют copy:
c := make([]int, len(a)) copy(c, a) c[0] = 99 fmt.Println(a) // [42 2 3], c — независимая копия
История
Сервис фильтрации данных начал возвращать неожиданные результаты: Один разработчик передавал срезы между несколькими функциями без копирования, меняя их состояние. Из-за модификаций слайсов в разных местах логика приложения ломалась, находились странные баги в данных, которые долго не могли отловить.
История
Потеря данных после передачи структуры: В одном проекте при сериализации данных по ошибке удаляли из структуры обязательное поле, потому что объект передавался по ссылке, а не создавалась его копия. В результате из-за этого терялась критичная информация на проде.
История
Ошибка параллельной работы с map: Разработчик скопировал ссылку на map, думая, что изменения не будут влиять на оригинал, как это бывает в других языках. В результате возникла гонка данных при работе в разных горутинах, что привело к падениям приложения.