Ответ
Технически — да, компилятор это позволяет. Однако делать это крайне небезопасно и не рекомендуется.
Причина в том, как устроена map
внутри. При добавлении новых элементов map
может вырасти, что приведет к перераспределению памяти для хранения данных (перехешированию). В этот момент старые ячейки памяти, где хранились значения, могут быть перемещены или удалены.
Если у вас есть указатель на значение в map
, и после этого map
изменяется (добавляется или удаляется элемент), ваш указатель может стать невалидным — он будет указывать на мусор или на совершенно другое значение.
Пример, который может сломаться:
m := make(map[int]string)
m[1] = "hello"
ptr := &m[1] // Взяли указатель. На данный момент он валиден.
fmt.Println(*ptr) // Выведет "hello"
// Добавляем много элементов, чтобы спровоцировать рост map и перехеширование
for i := 2; i < 100; i++ {
m[i] = "world"
}
// После перехеширования указатель ptr может указывать на невалидную память.
// Дальнейшее его использование — неопределенное поведение.
*ptr = "oops" // Может вызвать панику или повредить данные!
fmt.Println(m[1]) // Результат непредсказуем
Вывод: Никогда не храните долгоживущие указатели на элементы map
. Если вам нужно изменить значение в map
, делайте это напрямую по ключу: m[key] = newValue
.