golang `for range` 遍历后结果列表都是同一个对象

589 阅读1分钟

for rang

为什么结果列表中,都是同一个对象呢?

userList 是 []User,pointList 是[]*User对象,遍历 userList,赋值给 pointList

pointList结果 [&{u2},&{u2}] 为什么?

func TestXph20218151054(t *testing.T) {
	type User struct {
		Name string
	}
	userList := []User{{Name: "u1"}, {Name: "u2"}}

	pointList := make([]*User, 0)
	for _, v := range userList {
		t.Logf("%p", &v)
		pointList = append(pointList, &v)
	}

	for _, v := range pointList {
		t.Logf("%v", v)
	}
}

打印结果,发现v的地址每次都一样,

=== RUN   TestXph20218151054
		
   // v 每次遍历的地址
    demo_test.go:24: 0xc0000a0500
    demo_test.go:24: 0xc0000a0500
    
    // pointList的中的 值
    demo_test.go:29: &{u2}
    demo_test.go:29: &{u2}
--- PASS: TestXph20218151054 (0.00s)

分析结果

为什么 pointList中的值都一样?

0、首先userList里面存放的都是 对象。

0、当我们将 for _,v := range useList 的 v 取地址 append(pointList,&v) 到 pointList中时,pointList中保存了, v的地址

0、随着循环遍历,v每次都会变化,直到 遍历结束,v变成了最后一个值

0、因为 pointList 里面存放了 都是 v的地址,所以 pointList都变为 userList的最后一个值了。

模拟遍历

模拟 for 循环的遍历,可知,v自己在所处的作用域内,始终都是同一个对象。

func TestXph20218151106(t *testing.T) {
	type User struct {
		Name string
	}
	pointList := []User{{Name: "u1"}, {Name: "u2"}}
  
        // 遍历第一条数据
	_0, v := 0, pointList[0]
	t.Logf("%p, v-%p", &_0, &v)
  
        // 遍历第二条数据
	_1, v := 0, pointList[1]
	t.Logf("%p, v-%p", &_1, &v)
}
 demo_test.go:11: 0xc000022358, v-0xc00004e500
 demo_test.go:14: 0xc000022368, v-0xc00004e500