Golang的for循环踩坑

前言

最近写项目用了太多的for循环,殊不知这么简单的一个操作竟然踩出大坑,记录一波!

for循环使用

下面来看一下项目中的一些用法

实例踩坑效果

1
2
3
4
5
6
7
8
9
10
11
12
func main() {
arr := []int{1, 2, 3}
newArr := []*int{}
for _, v := range arr {
newArr = append(newArr, &v)
}
for _, v := range newArr {
fmt.Println(*v)
}
}
$ go run main.go
3 3 3

看到这个结果的时候我其实是一脸懵逼的,这个问题起初我一个java程序员真是无法理解,后来直到我运行了如下的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func main() {
arr := []int{1, 2, 3}
newArr := []*int{}
for _, v := range arr {
fmt.Println("")
fmt.Printf("origin addr: %p value: %v", &v, v)
newArr = append(newArr, &v)
}
for _, s := range newArr {
fmt.Println("")
fmt.Printf("addr: %p value: %v", s, *s)
}
}
输出结果:
origin addr: 0xc0000a67a8 value: 1
origin addr: 0xc0000a67a8 value: 2
origin addr: 0xc0000a67a8 value: 3
addr: 0xc0000a67a8 value: 3
addr: 0xc0000a67a8 value: 3
addr: 0xc0000a67a8 value: 3

总结

总结就是golang的for循环是通过同一个地址槽来反复接值的!!!