Golang append struct问题

小弟今天开发项目,发现一个奇怪问题 首先小弟的信息是从数据库中取出来的,取出来预备组成[]struct 返回给前端,进行任务展示,这是前提 数据库中有任务三条, 任务 1:

{[{false 1KB-20KB}] [] []}} b5a33d9d-6512-11ea-8001-000000000000 {2 0 }

任务 2:

{[{true 1GB-1TB}] [] []}} fee23a86-6506-11ea-8001-000000000000 {2 0 }}

任务 3:

{[{false 1KB-2KB}] [] []}} 9b995076-6514-11ea-8002-000000000000 {2 0 }

我利用了 append,组合成一个[]struct,可是输出之后发现

[{{[] [{false 1KB-2KB}] [] []}} 9b995076-6514-11ea-8002-000000000000 {2 0 }},
 {{[]{false 1KB-2KB}] [] []}} fee23a86-6506-11ea-8001-000000000000 {2 0 }}, 
  {{[{false 1KB-2KB}] [] []}} b5a33d9d-6512-11ea-8001-000000000000 {2 0 }}]

所有的 false 都被固定成 1kb-2kb 了,小弟写过 python,怀疑是 deepcopy 或者是 copy 的问题,但是 golang 这里实在不熟,请各位大神给小弟一点点灵感吧,谢谢!

代码如下

var sync infimanage.Sync
    var synclists []infimanage.Sync
    // fmt.Println(msg)
    etcd, err := infidb.New()
    if err != nil {
        fmt.Println(err)
    }
    syncslist, err := etcd.GetPrefixAllValue("syncwork/")
    if err != nil {
        fmt.Println(err)
    }
    for _, syncs := range syncslist {
        json.Unmarshal([]byte(syncs), &sync)
        fmt.Println(sync)
        // 这里打印输出都是正常的
        fmt.Println("xxxxxxxxxxxxxxxxxx")
        synclists = append(synclists, sync)
    }
    // 这里就不正常了
    fmt.Println(synclists)
阅读 4.5k
2 个回答

你把变量sync的定义放在for循环里面试试看。

现在的代码因为sync是外面共用的变量,所以每次json.Unmarshal的时候都会改变这个值,如果infimanage.Sync是值类型,那是没问题的。这里也不知道你这个类型的定义,我猜测是这样的问题。

通过查看 go编译源码 可以了解到, for-range其实是语法糖,内部调用还是for循环,初始化会拷贝带遍历的列表(如array,slice,map),然后每次遍历的 v 都是对同一个元素的遍历赋值。
也就是说如果直接对 v 取地址,最终只会拿到一个地址,而对应的值就是最后遍历的那个元素

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题