I have the following pair defined in my go program
type pair struct {
a float64
b float64
}
Then I create a map:
dictionary map[string]pair
I first add one element:
dictionary["xxoo"] = pair{5.0, 2.0}
Then I am trying to do this:
dictionary["xxoo"].b = 5.0 // try to change from 2.0 to 5.0
The last line doesn't compile and it said "can not assign to it"
I want to know what's the reason for this?
In order to assign a value to a struct field, that struct must be "addressable". Addressability is covered in the "Address Operators" section of the language specification.
Map values aren't addressable to leave map implementations the freedom to move values around in memory as needed. Because map values aren't addressable, you you can't use a selector (.
) operator on the value to assign to the struct field. If you use a pointer type as the map value, i.e. map[string]*pair
, the pointer indirection satisfies the addressability requirement.
dict := make(map[string]*pair)
dict["xxoo"] = &pair{5.0, 2.0}
dict["xxoo"].b = 5.0
If you are working with values, you need to copy the existing value via assignment, or supply an entirely new value:
dict := make(map[string]pair)
dict["xxoo"] = pair{5.0, 2.0}
// copy the value, change one field, then reassign
p := dict["xxoo"]
p.b = 5.0
dict["xxoo"] = p
// or replace the value in full
dict["xxoo"] = pair{5.0, 5.0}
That's not legal for reasons described here:
Querying a map give a copy of the stored item, so there is no point assigning to it.
The recommended workaround is:
var xxoo = dictionary["xxoo"]
xxoo.b = 5.0
dictionary["xxoo"] = xxoo
It's forbidden as said in Thomas' answer. Use pointers instead.
dict := map[string]*pair{}
dict["xxoo"] = &pair{5.0, 2.0}
fmt.Println(dict["xxoo"].b) // 2
dict["xxoo"].b = 5.0
fmt.Println(dict["xxoo"].b) // 5
https://play.golang.org/p/nEr_WrQOly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With