例1
m := make(map[int]*int)
arr := []int{1, 2, 3, 4, 5}
for i, v := range arr {
m[i] = &v
}
for k, v := range m {
fmt.Println("k-->v", k, *v)
}运行结果
map是无序的,我们指关注value,value的值都是5,这时候是否有疑问,循环存储了arr,为什么结果都是5

先了解一下range的特性
for range每次都是拷贝原变量的副本,也就是值拷贝
在上面的例子中,我们拷贝并不是 arr[i]对应的地址,而是变量v的地址,v只是一个临时变量
我们修改代码再看
func main() {
m := make(map[int]*int)
//m1 := make(map[int]*int)
arr := []int{1, 2, 3, 4, 5}
for i, v := range arr {
m[i] = &v
fmt.Println(&v)
fmt.Println(*m[i])
}运行结果
0xc0000140d8
1
0xc0000140d8
2
0xc0000140d8
3
0xc0000140d8
4
0xc0000140d8
5
我们可以看到v的地址是不变的,变的是值
所以我们在例1中看到m每次存储的都是v的地址,看下面的代码,我们打印一下m
m := make(map[int]*int)
arr := []int{1, 2, 3, 4, 5}
for i, v := range arr {
m[i] = &v
}
fmt.Println(m)运行结果
map[0:0xc0000140d8 1:0xc0000140d8 2:0xc0000140d8 3:0xc0000140d8 4:0xc0000140d8]
k-->v 4 5
k-->v 3 5
k-->v 0 5
k-->v 1 5
k-->v 2 5
我们可以看到map元素地址都是一样的
那么就可以解释为什么都是元素都是5了,因为for range最后循环完毕,地址中的值是5,所以我们循环map,里面的值也都是5
例2
我们修改切片中的元素添加6,再次运行
m := make(map[int]*int)
arr := []int{1, 2, 3, 4, 5, 6}
for i, v := range arr {
m[i] = &v
}
fmt.Println(m)
for k, v := range m {
fmt.Println("k-->v", k, *v)
}
map[0:0xc0000140d8 1:0xc0000140d8 2:0xc0000140d8 3:0xc0000140d8 4:0xc0000140d8 5:0xc0000140d8]
k-->v 5 6
k-->v 0 6
k-->v 1 6
k-->v 2 6
k-->v 3 6
k-->v 4 6
里面的值都变成6了,这是因为range完毕最后一个值是6,所以循环遍历map只是打印的那个地址里面的值而已
总结
for range中value只是一个临时变量,是一个固定的地址,值是不断改变的,而且这个地址只存range完毕的最后一个值
接for和range比较
不妨再看一下for循环
func main() {
m := make(map[int]*int)
m1 := make(map[int]*int)
arr := []int{1, 2, 3, 4, 5, 6}
for i, v := range arr {
m[i] = &v
}
for i := 0; i < len(arr); i++ {
m1[i] = &arr[i]
}
fmt.Println(m1)
fmt.Println(m)
for k, v := range m {
fmt.Println("m:k-->v", k, *v)
}
for k, v := range m1 {
fmt.Println("m1:k-->v", k, *v)
}
}
map[0:0xc0000c0060 1:0xc0000c0068 2:0xc0000c0070 3:0xc0000c0078 4:0xc0000c0080 5:0xc0000c0088]
map[0:0xc0000aa058 1:0xc0000aa058 2:0xc0000aa058 3:0xc0000aa058 4:0xc0000aa058 5:0xc0000aa058]
m:k-->v 0 6
m:k-->v 1 6
m:k-->v 2 6
m:k-->v 3 6
m:k-->v 4 6
m:k-->v 5 6
m1:k-->v 0 1
m1:k-->v 1 2
m1:k-->v 2 3
m1:k-->v 3 4
m1:k-->v 4 5
m1:k-->v 5 6
有不对的地方请指正,蟹蟹!
版权声明:本文为rainbowIT原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。