Доступ к структуре на карте (без копирования)
Предполагая следующее
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
- Карты обычно представляют собой редко заполненные хеш-таблицы, которые перераспределяются, когда они превышают пороговое значение. Перераспределение создаст проблемы, когда кто-то держит указатели на значения
- Если вы не хотите создавать копию объекта, вы можете сохранить указатель на сам объект как значение
- .Когда мы ссылаемся на карту, возвращаемое значение возвращается "возвращаемым по значению", если я могу заимствовать терминологию, используемую в параметрах функции, редактирование возвращенной структуры не оказывает никакого влияния на содержимое карты