本文介绍了为什么不去允许获取地图值的地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 这与为什么要禁止使用(&)地图成员的地址,但是允许(&)分片元素?,但我对接受的答案不满意:切片由背衬 地图中的访问结构(无需复制)甚至更好,但其接受的答案表明,您无法修改地图中结构值的字段,因为您无法获取其地址(这是我的问题) 。 地图由像片段一样的内存结构(可能包括数组)支持。 我不能接受的地址的真正原因一个地图值? 我想修改地图结构值。地图中的数字值可以使用++或+ =来修改。 func icandothis(){ cmap:= make(map [int] complex64) cmap [1] + = complex(1,0) fmt.Println(cmap [1])$ b $ b} 但是无法修改结构值: b $ b $ float $ $ float $ $ xR + = cR xI + = cI } func but_i_cannot_do_this(){ cmap:= make(map [int] Complex) / /cmap[1].Add(Complex{1,0}) fmt.Println(cmap [1])$ b $ b} func so_i_have_to_do_this(){ cmap:= make(map [int] Complex)c:= cmap [1] c.Add(Complex {1,0}) cmap [1] = c fmt.Println(cmap [1])$ b $ b} 解决方案让我们从这个错误的索赔开始: 我想修改地图结构值。地图中的数字值可以使用++或+ =等运算符进行修改。 func icandothis(){ cmap:= make(map [int] complex64) cmap [1] + = complex(1,0) fmt.Println(cmap [1])$ b $ b} 让我们展开速记形式: 包裹主要 进口(fmt ) func icandothisShort(){ cmap:= make(map [int] complex64) cmap [1] + = complex(1,0) fmt .println(cmap [1])$ b $ b} func icandothisLong(){ cmap:= make(map [int] complex64) //赋值操作x op = y其中op是一个二元算术运算符 //相当于x = x op(y)但只计算一次x。 // cmap [1] + = complex(1,0)v:= cmap [1] // v =零值= complex(0,0)v = v + complex 1,0)// v = complex(0,0)+ complex(1,0)= complex(1,0) cmap [1] = v // cmap [1] = v = complex(1 ,0)a:= cmap [1] // a = complex(1,0) fmt.Println(a)// complex(1,0)} func main(){ icandothisShort() icandothisLong()} 游乐场: https://play.golang.org/p/1OgmI_AD9uN 输出: (1 + 0i)$ b $你可以在> icandothisLong()中看到 / code>,这是 icandothisShort()的扩展形式,没有更新。 下一个错误索赔, 真正的原因是您不了解地图数据结构。 p> 地图由桶内存结构支持。映射键通过不完美的动态哈希来标识当前的主桶。映射键和值存储在主存储区或溢出存储区中。随着地图条目的创建,更新和删除,地图存储区会不断重新组织。 地图条目在内存中没有固定位置。 做一些基础研究。例如, GopherCon 2016:Keith Randall - 在地图实施内部 This is the same as Why does go forbid taking the address of (&) map member, yet allows (&) slice element? but I'm not satisfied with the accepted answer: "Slices are backed by a backing array and maps are not."The question Access Struct in Map (without copying) is even better, but its accepted answer says you can't modify a field of a struct value in a map because you cannot take its address (which is my question).Maps are backed by memory structures (possibly including arrays) just like slices are.So what is the real reason why I can't take the address of a map value?I wanted to modify a map struct value in place. Numeric values in maps can be modified in place using operators like ++ or += func icandothis() { cmap := make(map[int]complex64) cmap[1] += complex(1, 0) fmt.Println(cmap[1]) }But struct values cannot be modified:type Complex struct { R float32 I float32}func (x *Complex) Add(c Complex) { x.R += c.R x.I += c.I}func but_i_cannot_do_this() { cmap := make(map[int]Complex) //cmap[1].Add(Complex{1, 0}) fmt.Println(cmap[1])}func so_i_have_to_do_this() { cmap := make(map[int]Complex) c := cmap[1] c.Add(Complex{1, 0}) cmap[1] = c fmt.Println(cmap[1])} 解决方案 Let's start with this false claim:Let's expand the shorthand form:package mainimport ( "fmt")func icandothisShort() { cmap := make(map[int]complex64) cmap[1] += complex(1, 0) fmt.Println(cmap[1])}func icandothisLong() { cmap := make(map[int]complex64) // An assignment operation x op= y where op is a binary arithmetic operator // is equivalent to x = x op (y) but evaluates x only once. // cmap[1] += complex(1, 0) v := cmap[1] // v = zero value = complex(0, 0) v = v + complex(1, 0) // v = complex(0, 0) + complex(1, 0) = complex(1, 0) cmap[1] = v // cmap[1] = v = complex(1, 0) a := cmap[1] // a = complex(1, 0) fmt.Println(a) // complex(1, 0)}func main() { icandothisShort() icandothisLong()}Playground: https://play.golang.org/p/1OgmI_AD9uNOutput:(1+0i)(1+0i)As you can see in icandothisLong(), the expanded form of icandothisShort(), there is no update in-place.The next false claim,The real reason is that you don't understand the map data structure.Maps are backed by bucket memory structures. A map key, through an imperfect, dynamic hash, identifies a current primary bucket. The map keys and values are stored in the primary bucket or an overflow bucket. The map buckets are constantly reorganized as map entries are created, updated, and deleted. A map entry has no fixed location in memory. Do some basic research. For example,GopherCon 2016: Keith Randall - Inside the Map Implementation 这篇关于为什么不去允许获取地图值的地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-19 04:41