loopsgoboltdb

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


So I have this var resolve of type map[string][]byte that is being initialised by calling a method. If I just iterate resolve the value is being printed correctly.

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

But in the very next line I am trying to iteration over the map to store the values in a db (bolt), in that value for a key (key1) in the map is being changed automatically and I am not able to figure out why. To further simplify that what I did is stored the value for that key in a new var

a:= resolve["key1"]

and then while storing the values in the db I checked if the key is key1 store a. In that case also the value of a is being changed which should not.

This gist has code we would be able to see that resolve that we have in line 30 has been change in line 34.

I have added the code in the go playground here is the link https://play.golang.org/p/2WacK-xxRp_m


Solution

  • On your line in readAll:

    lGraceP[string(k)] = v
    

    you're storing the value for later use. The documentation specifies that the value v is not valid after the transaction ends.

    From Cursor.First (and there's similar text in Cursor.Next) in the bolt library (see the highlighted text):

    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.

    The way that the key and value are only valid for the life of the transaction is that the array underlying their slices are re-used. That causes your values to mutate unexpectedly.