Let's say I have a simple struct a with a string property b:
type A struct {
B string
}
The following code using an array of A types:
testArray := []A{A{}}
testArray[0].B = "test1"
fmt.Println(testArray[0].B)
Will print out "test1" as expected.
But this code that seems equally simple:
testMap := make(map[string]A)
testMap["key"] = A{}
testMap["key"].B = "test2"
fmt.Println(testMap["key"].B)
Will not print out "test2" but instead will result in the following error:
cannot assign to testMap["key"].B
So, why does assigning to the subproperty in a map result in an error while assigning to the subproperty in an array work as expected? I want to know both why this doesn't work for maps AND why it does work for arrays. I would also love some speculation on why they designed the language with this difference between the two data structures.
In the Go language, you can set a struct of an array. To do so see the below code example. Where type company struct has a slice of type employee struct. Here, you can see the two different structs, and the employee struct is used as an array in the company struct.
Slices in Go and Golang The basic difference between a slice and an array is that a slice is a reference to a contiguous segment of an array. Unlike an array, which is a value-type, slice is a reference type. A slice can be a complete array or a part of an array, indicated by the start and end index.
struct has other advantages over array which can make it more powerful. For example, its ability to encapsulate multiple data types. If you are passing this information between many functions, a structure is likely more practical (because there is no need to pass the size).
I answered at some length on the mailing list, but the short explanation is that this doesn't work because map entries are not addressable. What that means is that you can't take the address of an entry in a map. And that is because adding a new value to a map may cause map entries to shift around, so that the addresses change. Because you can't take the address of an entry in a map, all map operations use whole values: copy a whole value out of a map, add a whole to a map. Assigning to one field of a struct in a map would require a read-modify-write operation, that maps do not support (they could, but they don't, and there is a cost to supporting them).
Elements in arrays and slices are addressable because they do not move around after they have been created.
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