Tips: for range creates a copy of each element instead of directly returning a reference to each element
Example 1:
package main import "fmt" func main() { slice := []int{0, 1, 2, 3} myMap := make(map[int]*int) for index, value := range slice { myMap[index] = &value } ("=====new map=====") prtMap(myMap) } func prtMap(myMap map[int]*int) { for key, value := range myMap { ("map[%v]=%v\n", key, *value) } }
Output:
dotzdeMacBook-Pro-2:src dotz$ ./range
=====new map=====
map[0]=3
map[1]=3
map[2]=3
map[3]=3
Example 2:
package main import "fmt" type Test struct { name string } func (this *Test) Point() { // this is a pointer () } func main() { ts := []Test{{"a"}, {"b"}, {"c"}} for _, t := range ts { defer () //Output c c c c } }
Output:
dotzdeMacBook-Pro-2:src dotz$ ./method
c
c
c
Example 1 We expect outputs 0, 1, 2, 3, Example 2 We expect outputs a, b, c, but the outputs of both examples are not what we expected.
For Example 1, it is obvious that the address is fetched, and the address of the value variable is taken every time. Therefore, the values of all elements in the map are the addresses of the value variable (references), because the last value is assigned to 3, and all outputs are 3.
For Example 2, it is a bit obscure, which is mixed with the rules of defer and method receiver, but in fact, it is the same as Example 1. When executing(), the address (reference) of t is obtained. At the end of for, t is assigned to the address of "c". When the main function returns, the receiving method Point of "c" is executed, so the output is "c".
Supplement: golang address fetching operation pit: for idx,item := range arr The item in the item is an independent object
Let's look at the code first:
package main import "fmt" func main() { type s struct { A string B int32 } arr := []s{ {"123", 123}, {"456", 456}, {"789", 789}, } m := make(map[string]*s) for idx, item := range arr { m[] = &item ("idx=%d, addr=%p, item addr=%p\n", idx, &arr[idx], &item) } for k, v := range m { ("key=%s, v=%+v\n", k, v) } }
Run output:
idx=0, addr=0xc00004e050, item addr=0xc0000044a0
idx=1, addr=0xc00004e068, item addr=0xc0000044a0
idx=2, addr=0xc00004e080, item addr=0xc0000044a0
key=123, v=&{A:789 B:789}
key=456, v=&{A:789 B:789}
key=789, v=&{A:789 B:789}
I foolishly took the address of the item in the loop, and as a result, all the values in the map point to the last one!
It seems that item is an independent object, which points to the corresponding element in the array.
The above is personal experience. I hope you can give you a reference and I hope you can support me more. If there are any mistakes or no complete considerations, I would like to give you advice.