Golang for 循环中append操作的坑

844 阅读1分钟

一 问题来源

最近做的一个项目中 ,在使用for循环,遍历用户信息时,遇到一个坑,觉得很容易用错 ,故写下这篇文章来警示自己。

二 问题描述

简单的说,就是我在使用for range对slice进行append地址操作,append完之后,遍历结果,发现结果值都一样。用代码示例,如下:
func main() {
	var out []*int
	for i := 0; i < 3; i++ {
		out = append(out, &i)
	}
	fmt.Println("Values:", *out[0], *out[1], *out[2])
	fmt.Println("Addresses:", out[0], out[1], out[2])
}

得到的结果如下:

Values: 3 3 3
Addresses: 0xc000016050 0xc000016050 0xc000016050

三 出现的原因

在for range的过程中,变量i只被创建了一次,变量i有自己的空间内存且地址在for循环过程中不变,循环过程中每次将i进行值传递。这样append到out里面的是i的地址,且每次都一样。循环到最后一个的时候,out里面的值就跟最后的一个相同了。

四 解决策略

最简单的办法就是把变量i赋值到一个新的变量上,这样就不会出现该问题了
func main() {
	var out []*int
	for i := 0; i < 3; i++ 
		i := i
		out = append(out, &i)
	}
	fmt.Println("Values:", *out[0], *out[1], *out[2])
	fmt.Println("Addresses:", out[0], out[1], out[2])
}
Values: 0 1 2
Addresses: 0xc00007e020 0xc00007e028 0xc00007e030

参考来源