开发者社区 问答 正文

golang中for循环读取map结果不正确

代码如下

package main

import "fmt"

type Foo struct {
   bar string
}
func main() {
   list := []Foo{
      {"A"},
      {"B"},
      {"C"},
   }
   list2 := make([]*Foo, len(list))
   for i, value := range list {
      //fmt.Printf("%p\n",&value)
      list2[i] = &value
   }
   fmt.Println(list[0], list[1], list[2])
   fmt.Println(list2[0], list2[1], list2[2])
}

运行结果如下

{A} {B} {C}
&{C} &{C} &{C}

为什么list2的结果内容全是C呢?

展开
收起
道月芬1 2021-10-20 05:53:45 377 分享 版权
阿里云 AI 助理回答

从您的代码片段来看,您正在使用Go语言创建一个结构体Foo并初始化一个包含该结构体元素的切片list。之后,您尝试创建一个新的切片list2,其元素为Foo结构体的指针。这里,您想把list中的每个元素的地址赋值给list2的对应位置。但是,您在注释掉了打印指针的语句,并且在循环体内没有完成将list中的元素地址赋给list2的操作。

为了完成这个任务,您需要解除对value的引用并取其地址来赋值给list2中的相应位置。下面是修改后的代码:

package main

import "fmt"

type Foo struct {
    bar string
}

func main() {
    list := []Foo{
        {"A"},
        {"B"},
        {"C"},
    }
    list2 := make([]*Foo, len(list))
    for i, value := range list {
        // 正确地获取value的地址并赋值给list2
        list2[i] = &value
        // 打印每个元素的地址以验证操作
        fmt.Printf("Address of element %d in list2: %p\n", i, list2[i])
    }
}

这段代码中,我做了以下修改: 1. 解除了对value的引用,并通过&value获取了它的地址。 2. 将获取到的地址赋值给了list2的对应位置,即list2[i] = &value。 3. 取消了对打印指针的注释,并调整了打印语句,以便于观察每个元素在list2中的地址。

请注意,由于Go的range循环中对结构体的遍历会复制结构体实例,因此这里的&value实际上每次循环都会产生一个新的地址。这意味着,尽管这样可以编译和运行,但最终list2中的所有元素都可能指向同一个临时变量的地址(具体行为可能会因编译器优化而异)。为了避免这种情况,更推荐直接用结构体的地址填充list2,如下所示:

for i := range list {
    list2[i] = &list[i]
}

这样可以直接获取list中每个元素的地址,避免了不必要的复制问题。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答