Here's a short example to demonstrate:
package main
import "fmt"
func main() {
array := [3]int{1, 2, 3}
array[0]++ // Works
slice := make([]int, 3)
for i := range slice {
slice[i] = i + 1
}
arrayMap := make(map[int][3]int)
sliceMap := make(map[int][]int)
arrayMap[0] = array
sliceMap[0] = slice
//arrayMap[0][0]++ // Does not compile: "cannot assign to arrayMap[0][0]"
sliceMap[0][0]++
fmt.Println(arrayMap)
fmt.Println(sliceMap)
}
Why can I not modify the contents of an array if it's inside a map, even though they are mutable outside the map? And why does this work with slices?
For maps, its values are not addressable. That is, when you use a value type
(arrays are value types
in Go), you cannot address the value using ++
.
But, if you use a reference type
(slices are reference types
in Go), you can as you already alluded to in the example.
This holds true regardless of type used in the Map.
One thing we can do instead is to use the ptr address of the type. For example, if you take the address of the array, then it should work:
Playground: http://play.golang.org/p/XeIThVewWD
package main
import "fmt"
func main() {
array := [3]int{1, 2, 3}
slice := []int{1, 2, 3}
arrayMap := make(map[int]*[3]int) // use the pointer to the type
sliceMap := make(map[int][]int)
arrayMap[0] = &array // get the pointer to the type
sliceMap[0] = slice
arrayMap[0][0]++ // works, because it's a pointer to the array
sliceMap[0][0]++
fmt.Println(*arrayMap[0])
fmt.Println(sliceMap[0])
}
// outputs
[2 2 3]
[2 2 3]
This works and increments the [0]
index of array
to 2
, as expected.
It works because Go graciously dereferences pointers for us to its value when read and updates the value during re-assignment.
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