映射中键的值在 golang 中自动更改

value for a key in a map is being changed automatically in golang

所以我有这个类型为 map[string][]byte 的变量 resolve,它正在通过调用方法进行初始化。如果我只是迭代 resolve 值被正确打印。

for k, v := range resolve {
        fmt.Printf("%s\t%s\n", k, v)
}

但在下一行中,我试图在地图上迭代以将值存储在数据库 (bolt) 中,在地图中的键值 (key1) 中正在自动更改,我无法弄清楚原因。 为了进一步简化,我所做的是将该键的值存储在一个新的 var

a:= resolve["key1"]

然后在将值存储在数据库中时,我检查了键是否是 key1 store a。在这种情况下,a 的值也会被更改,但不应该更改。

这个 gist 有代码,我们可以看到我们在第 30 行中的 resolve 已在第 34 行中更改。

我已经在 go playground 中添加了代码,这里是 link https://play.golang.org/p/2WacK-xxRp_m

问题一定出在 BoltDB 的某个地方,以及它如何处理为同一个键写入更大的值。如果我们不增加尺寸

dbData["1"] = []byte("vivek-9"))

然后它起作用了(因为其他值不受影响)。尝试快速浏览 boltdb/bolt,但到目前为止没有任何内容跳出。

如果我猜的话,您从 ReadAll 获得的字节片是“windows”到一个大的支持字节数组中。当您插入一个更大的值时,它会导致后续字节移位。但是 windows 没有移动,所以他们现在正在观察不同的数据。在 ReadAll 中克隆您的值,这会有所帮助。

在线readAll

lGraceP[string(k)] = v

您正在存储该值供以后使用。文档指定值 v 在事务结束后无效。

来自螺栓库中的 Cursor.First(并且 Cursor.Next 中有类似的文本)(参见突出显示的文本):

First moves the cursor to the first item in the bucket and returns its key and value. If the bucket is empty then a nil key and value are returned. The returned key and value are only valid for the life of the transaction.

键和值仅在事务生命周期内有效的方式是重新使用其切片下的数组。这会导致您的价值观发生意外变化。