首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在go中修改地图的约定

在go中修改地图的约定
EN

Stack Overflow用户
提问于 2019-06-04 08:43:09
回答 1查看 113关注 0票数 -2

在go中,通过重新赋值或使用指针值来修改map是一种更常见的做法吗?

代码语言:javascript
复制
type Foo struct {
    Bar int
}

重新分配:

代码语言:javascript
复制
foos := map[string]Foo{"a": Foo{1}}
v := foos["a"]
v.Bar = 2
foos["a"] = v

vs指针

代码语言:javascript
复制
foos := map[string]*Foo{"a": &Foo{1}}
foos["a"].Bar = 2
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-05 03:17:22

您可能(无意中)混淆了这里的问题。

将指针存储在map中的原因不是为了使“点域”修改有效-而是为了保留map“保留”的值的确切位置。

Go映射的一个重要属性是绑定到它们的键的值是不可寻址的。换句话说,你不能合法地做像这样的事情

代码语言:javascript
复制
m := {"foo": 42}
p := &m["foo"] // this won't compile

原因是Go语言的特定实现可以自由地实现映射,从而允许它们围绕它们所持有的值移动。这是必要的,因为映射通常实现为平衡树,并且这些树在删除和/或添加新条目后可能需要重新平衡。因此,如果the language specification允许获取保存在映射中的值的地址,就会禁止映射来回移动其值。

这就是为什么如果映射值具有struct类型,您就不能“就地”修改它们,而必须“批量”替换它们的原因。

通过扩展,当您向map添加一个元素时,该值将被复制到map中,并且当map重新排列其条目时,它也会被复制(移动)。

因此,将指针存储到映射中的主要原因是保留要由映射“索引”的值的“身份”-使它们仅存在于内存中的单个位置-和/或防止过多的内存操作。如果不引入bug-sync.Mutex或者包含bug的struct类型就是一个很好的例子,有些类型甚至无法明智地复制。

回到你的问题上来,在map中使用指针来达到你建议的目的可能是一个很好的技巧,但要注意这是一种代码味道:当决定关于map的值与指针时,您应该相当关注上面概述的考虑因素。

²至少有两个是积极维护的:一个是“股票”,一个是"gc",还有一部分是“GCC”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56436067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档