Go Range的奇怪机制¶
在Go1.22.0中已经得到修正,如果go.mod声明为1.22.x版本,会自动使用新的语义
在下面的代码中,请问输出是什么?
l := []int{1, 2, 3}
for _, v := range l {
fmt.Printf("%d, %p", v, &v)
}
答案是:
1 某个地址A
2 A
3 A
range
得到的v
值不一样,但是地址一样呢?
假设Go是一家漫画店的老板,最近有个3页的漫画,你想去看。Go老板拿出一台pad,上面一次只能显示一页漫画。于是,你通过同一个pad读取了三页不同的漫画。
这就是range的设计方式,Go认为你通过range是想读一个变量,而不是得到变量本身。于是,在遍历一个元素var A []T
的时候Go会开辟一个类型T
的一块空间,每次遍历,就从A
的对应位置读值,赋给开辟的空间。也就是说,每次遍历都是在同一个内存地址读副本。
那么如果是想进行如列表元素append之类的操作怎么办呢?在for的下面加一行就好:
v := v