go - 结构值的 slice 总是被最后一个索引覆盖

标签 go

我无法理解此代码块的行为。我做错了什么,正确的做法应该是什么?

import (
    "fmt"
    "strconv"
)

type Record struct {
    name *string
}
type person struct {
    name string
}

func main() {
    var Records []*Record
    var persons []person
    for i := 0; i < 10; i++ {
        newValue := person{name: strconv.Itoa(i)}
        persons = append(persons, newValue)
    }
    for _, personone := range persons {
        newRecord := &Record{}
        getName(newRecord, &personone)
        Records = append(Records, newRecord)
    }
    for _, record := range Records {
        fmt.Println(*record.name)
    }

}

func getName(record *Record, value *person) {
    record.name = &value.name
}

我希望这段代码打印 0 到 9,但它总是打印 9,即最后一个值。

最佳答案

for _, personone := range persons {

在此语句中,personone 是一个声明一次并在每次迭代时被覆盖的变量。

然后你在这条语句getName(newRecord, &personone)中获取它的地址。

因此您每次都传递相同的地址,该地址在每次迭代中都会发生变化。

所以你最终得到了相同的值,因为你分配了相同的地址。

如何解决:如果您实际上不需要指针,请不要使用它们。

一个 super 肮脏的 hack 是显式地复制结构 https://play.golang.org/p/Sp4xD88rfvE

for _, personone := range persons {
    personone := personone // <-- see here
    newRecord := &Record{}
    getName(newRecord, &personone)
    Records = append(Records, newRecord)
}

但我真的不建议你那样做

关于go - 结构值的 slice 总是被最后一个索引覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52140889/

相关文章:

string - 如何在String方法中打印原始go struct

go - 在golang html/template中对 slice 进行排序?

google-app-engine - 如何在 Go 中的 AppEngine 数据存储区中建立多对多关系模型?

go - 用于Kerberos身份验证的librd Kafka配置设置

go - Go中的短路评估

sql - 使用golang批量插入复制sql表

loops - 完成 2 个 goroutine 后删除文件

networking - UDPConn Close 到底做了什么?

go - 引用本地的 Go 模块

mysql - Go 中的 ORM/ORM 类库