In the first case (without declaring and assigning an inner variable), the variable item
is always the same and gets assigned a copy of the element in each iteration, so setting newMap["0"]
with a pointer to item
will effectively leave newMap["0"]
set to the last element in the iteration, i.e. {delete 3rd-value}
, because it points to item
.
If instead you assign item
to a new variable in the loop, and then assign a pointer to that new variable to the map, then the third iteration won’t affect what’s in newMap["0"]
, as it points to a different address, not that of the range’s item
variable but of the inner declared one.
Look at this example (or check it on the playground at Go Playground - The Go Programming Language):
package main
import (
"fmt"
)
func main() {
a := [3]int{1, 2, 3}
fmt.Printf("array addresses: %p, %p, %p\nvalues: %d, %d, %d\n\n", &a[0], &a[1], &a[2], a[0], a[1], a[2])
var b *int
for i, v := range a {
if i < 1 {
b = &v
}
}
fmt.Printf("b address: %p\nvalue: %d\n\n", b, *b)
for _, v := range a {
c := &v
*c = *c + 1
fmt.Printf("c address: %p\nvalue: %d\n\n", c, *c)
}
for _, v := range a {
c := v
c = c + 1
fmt.Printf("c address: %p\nvalue: %d\n\n", &c, c)
}
fmt.Printf("array addresses: %p, %p, %p\nvalues: %d, %d, %d\n", &a[0], &a[1], &a[2], a[0], a[1], a[2])
for i := 0; i < len(a); i++ {
a[i]++
}
fmt.Printf("array addresses: %p, %p, %p\nvalues: %d, %d, %d\n", &a[0], &a[1], &a[2], a[0], a[1], a[2])
}
The output will look like this:
array addresses: 0x416020, 0x416024, 0x416028
values: 1, 2, 3
b address: 0x416038
value: 3
c address: 0x416040
value: 2
c address: 0x416040
value: 3
c address: 0x416040
value: 4
c address: 0x416050
value: 2
c address: 0x416058
value: 3
c address: 0x416060
value: 4
array addresses: 0x416020, 0x416024, 0x416028
values: 1, 2, 3
array addresses: 0x416020, 0x416024, 0x416028
values: 2, 3, 4
Here you can see how b
is assigned a pointer to v
only on the first iteration, but its final value is that of a[2]
, as v
is just one variable that gets copied the elements of a
on each iteration, and b
is pointing to it so it will also change.
The second loops explicitly shows that v
is just one variable, as taking its address always prints the same.
The last loop shows that when declaring and assigning v
to a new variable c
, on each iteration c
is a new variable with a different address.
Finally, you can see how all of this didn’t affect the array a
, as its elements were always copied in the range loop, while doing it with a plain for loop allows to change the elements.