Доступ к структуре на карте (без копирования)

Предполагая следующее

type User struct {
    name string
}

users := make(map[int]User)

users[5] = User{"Steve"}

Почему не удается получить доступ к экземпляру struct, который теперь хранится на карте?

users[5].name = "Mark"

Может ли кто-нибудь пролить свет на то, как получить доступ к структурированной карте или логике, почему это невозможно?

Примечания

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

Я также знаю, что это можно сделать, сохранив указатели на моей карте, но я тоже не хочу этого делать.

Ответ 1

Основная проблема заключается в том, что вы не можете взять адрес чего-то на карте. Вы могли бы подумать, что компиляция переделает users[5].name = "Mark" в это

(&users[5]).name = "Mark"

Но это не скомпилируется, давая эту ошибку

cannot take the address of users[5]

Это позволяет картам свободно переупорядочивать вещи по своему желанию эффективно использовать память.

Единственный способ изменить что-то на самом деле на карте - это назначить ему, т.е.

t := users[5]
t.name = "Mark"
users[5] = t

Поэтому я думаю, вам либо придется жить с копией выше, либо жить с сохранением указателей на вашей карте. Хранение указателей имеет недостаток в использовании большего объема памяти и дополнительных распределений памяти, которые могут перевесить копирование выше - только вы и ваше приложение можете это сказать.

Третий вариант - использовать срез - ваш оригинальный синтаксис отлично работает, если вы меняете users := make(map[int]User) на users := make([]User, 10)

Ответ 2

  1. Карты обычно представляют собой редко заполненные хеш-таблицы, которые перераспределяются, когда они превышают пороговое значение. Перераспределение создаст проблемы, когда кто-то держит указатели на значения
  2. Если вы не хотите создавать копию объекта, вы можете сохранить указатель на сам объект как значение
  3. .Когда мы ссылаемся на карту, возвращаемое значение возвращается "возвращаемым по значению", если я могу заимствовать терминологию, используемую в параметрах функции, редактирование возвращенной структуры не оказывает никакого влияния на содержимое карты