【问题标题】:Converting array of struct to array of pointers fails [duplicate]将结构数组转换为指针数组失败[重复]
【发布时间】:2020-10-02 23:45:15
【问题描述】:
package main

import (
    "fmt"
)

type test struct {
    Name string
}

func main() {
    foo := []test{
        {Name: "a"},
        {Name: "b"},
    }
    var bar []*test
    for _, item := range foo {
        fmt.Printf("%v\n", item.Name)
        bar = append(bar, &item)
    }
    
    for _, item := range bar {
        fmt.Printf("%v\n", item.Name)
    }
}

当我运行上面的代码时,我希望看到输出

a
b
a
b

但是,输出是

a
b
b
b

发生了什么事?

作为参考,这是在 go playground 中完成的

【问题讨论】:

  • 循环重复使用相同的指针。将fmt.Printf("%p\n", &item) 添加到循环中即可查看。

标签: go


【解决方案1】:

Golang 源码

// len_temp := len(range)
// range_temp := range
// for index_temp = 0; index_temp < len_temp; index_temp++ {
//     value_temp = range_temp[index_temp]
//     index = index_temp
//     value = value_temp
//     original body
//   }

Range 实际上是for 循环的语法糖。在内部,它仍然使用for 循环,它将首先复制array 的所有元素并循环遍历它们并将每个索引和值分配给temp 变量。在检索值的地址时,它实际上采用了temp 变量的地址,而新的array 实际上会让每个元素都指向同一个地址。

修复

for i, _ := range foo {
    p := foo[i]
    fmt.Printf("%v\n",  p.Name)
    bar = append(bar, &p)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 2018-03-27
    • 2012-03-28
    • 1970-01-01
    • 2015-05-30
    • 2017-01-19
    • 1970-01-01
    相关资源
    最近更新 更多