栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

关于for range中只存最后一个元素的问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于for range中只存最后一个元素的问题

例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

 有不对的地方请指正,蟹蟹!

参考:【golang】 关于for range中只存储最后一个元素的问题 - 要坚持的girl - 博客园

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1038658.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号