V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
PEIENYKYK
V2EX  ›  Go 编程语言

Golang append struct 问题,请诸位大神留步一观

  •  
  •   PEIENYKYK · 2020-03-15 19:21:54 +08:00 · 1763 次点击
    这是一个创建于 1503 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小弟今天开发项目,发现一个奇怪问题 首先小弟的信息是从数据库中取出来的,取出来预备组成[]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 这里实在不熟,请各位大神给小弟一点点灵感吧,谢谢!

    第 1 条附言  ·  2020-03-15 20:33:05 +08:00

    附上代码

    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)
    
    7 条回复    2020-03-16 10:47:41 +08:00
    vus520
        1
    vus520  
       2020-03-15 20:38:59 +08:00
    看不懂,是我的话就提前定义好 struct,取出来以后全还原到 struct 对象,再处理
    whoami9894
        2
    whoami9894  
       2020-03-15 20:39:30 +08:00 via Android
    全部都 unmarshal 到同一块内存了,你应该每轮迭代定义个新 sync
    PEIENYKYK
        3
    PEIENYKYK  
    OP
       2020-03-15 20:42:00 +08:00
    @whoami9894 对,您的点拨很到位,谢谢谢谢!感恩
    newmiao
        4
    newmiao  
       2020-03-15 20:50:01 +08:00
    好像知乎上看到你的问题,回答了你,怀疑是 for-range 用了指针,参考: https://mp.weixin.qq.com/s/klJBAi5LvdJOGvma2Ir0OA
    bintianbaihua
        5
    bintianbaihua  
       2020-03-15 21:09:59 +08:00
    for-range 的经典坑。
    whoami9894
        6
    whoami9894  
       2020-03-15 22:25:03 +08:00
    @whoami9894 #2
    又看了一下,还有点问题
    如果你那个`infimanage.Sync`是个 interface 并且实际类型是个 pointer 的话才会出现我#2 说的问题,不过看你最后生成的数据里只有`{false 1KB-2KB}`相同,后面的 uuid 是不同的,那么就排除我#2 说的情况。猜测是你后两次迭代的 JSON 数据中`{false 1KB-2KB}`字段有误(比如字段名出错),导致只 unmarshal 了后面的正常数据到你复用的 sync 里,然后把 sync 的拷贝 append

    而且你粘贴的输出明显有问题:
    `{[] [{false 1KB-2KB}] [] []}}`
    `{[]{false 1KB-2KB}] [] []}}`
    `{[{false 1KB-2KB}] [] []}}`
    建议按上面几点自己排查一下
    rrfeng
        7
    rrfeng  
       2020-03-16 10:47:41 +08:00
    把第一行 var sync infimanage.Sync 挪到 for 循环里面。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2882 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:32 · PVG 15:32 · LAX 00:32 · JFK 03:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.