Можно ли в Go брать указатель на значение в `map`?

Ответ

Технически — да, компилятор это позволяет. Однако делать это крайне небезопасно и не рекомендуется.

Причина в том, как устроена 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.