代码改变世界

golang 学习笔记 -- for

2023-08-22 10:13  默默不语  阅读(8)  评论(0编辑  收藏  举报
  1. for range 
    1. 遍历取不到所有元素的指针
orgItems := []int{1, 2, 3}
var newItems []*int
for _, item := range orgItems {
    fmt.Println(item) // 1 2 3
    fmt.Printf("%p\n", &item) // 每次地址都是相同的
    newItems = append(newItems, &item)
}
    
for _, item := range newItems {
    fmt.Println(*item)    
}
// expect
// 1
// 2
// 3
// actually
// 3
// 3
// 3
    原因: 因为 for-range 在遍历值类型时,其中的 item 变量是一个的拷贝,当使用 获取指针时,实际上是获取到 item 这个临时变量的指针,而 v变量在 for-range 中只会创建一次,之后循环中会被一直重复使用。 在 newItems 中保存的都是 item 这个临时变量的地址,而 &item 最终会指向 orgItems 最后一个元素的值拷贝, 所以输出的都是最后一个元素。
    解决方法:
    • 使用局部变量拷贝
for _, item := range orgItems {
    copied := item
    fmt.Println(copied) // 1 2 3
    fmt.Printf("%p\n", &copied) // 每次地址都是相同的
    newItems = append(newItems, &copied)
}
    • 通过索引获取 slice 原值
for i := range orgItems {
    newItems = append(newItems, &orgItems[i])
}