golang slice 迭代值的地址为何不变?

看一段 golang 代码:

package main

import "fmt"

func main() {
    x := make([]int, 3)

    x[0], x[1], x[2] = 1, 2, 3

    for i, val := range x {
        fmt.Println(&x[i], "vs.", &val)
    }
}

运行结果:

0xc42007c080 vs. 0xc42006c178
0xc42007c088 vs. 0xc42006c178
0xc42007c090 vs. 0xc42006c178

迭代这个切片的时候,切片索引地址是不同的,而不同的值的地址是相同的,主要不理解值的地址为很么相同?这又说明了什么?

希望有人能够通俗易懂,正确无误的讲一下,谢谢!

阅读 4.9k
3 个回答

for i,val := range x 可以等价看为:

var val int
var length = len(x)
for i:=0; i<length; i++ {
    val = x[i]
}

所以val的地址不变,而且val是值拷贝,修改它也不会影响原数组。

for range是值拷贝
所以val这个临时变量的地址固定不变的,值在变

1楼正解。for i, val := range,这里的val是个拷贝的值。经常能看到这样写的代码,这里是int型的slice还好,如果是一个struct型的slice,那这个拷贝开销还是可观的。所以,还是建议通过下标直接访问slice中的内容,这样可以避免几次拷贝开销。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题