douyinglan2599 2018-04-26 05:31
浏览 50
已采纳

json解组后缺少struct对象的嵌套数组

I ran into some problem with unmarshalling string back to struct object when the object has a nested array of struct objects. I use the following code as a demo for my problem:

The json string is

const myStr = `{
  "name": "test_session1",
  "shared_items:": [
    {
      "id": 0,
      "name": ".aspnet"
    },
    {
      "id": 1,
      "name": ".bash_profile"
    }
  ]
}`

I have two structs as following with Session being the parent and SharedItem being the associated child(ren):

type Session struct {
    ID              uint64           `json:"id"`
    Name            string           `json:"name,omitempty"`
    SharedItems     []SharedItem `json:"shared_items"`
}

type SharedItem struct {
    ID          uint64 `json:"id"`
    Name        string `json:"name"`
}

I tried the following to unmarshal the json string, but it looks like the nested array of SharedItem objects are missing, as I saw sess object has 0 shared items, which is not what I expected.

func main() {
    var sess Session
    if err := json.Unmarshal([]byte(myStr), &sess); err != nil {
        panic(err)
    }
    fmt.Printf("sess name is: %s, and has %d shared items
", sess.Name, len(sess.SharedItems)) // printed: sess name is test_session1, and has 0 shared items
}

Here's the link to my go playground: https://play.golang.org/p/a-y5T3tut6g

  • 写回答

1条回答 默认 最新

  • doujianzhi3358 2018-04-26 05:51
    关注

    Golang Spec for json unmarshal describe it all

    To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. By default, object keys which don't have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).

    In the json provided the json object for shared items has : colon in it as we can see it is shared_items: not shared_items which is our json tag

      "shared_items:": [
        {
          "id": 0,
          "name": ".aspnet"
        },
        {
          "id": 1,
          "name": ".bash_profile"
        }
      ]
    

    Either remove : or append into your struct json tag to match the same.

    package main
    
    import (
        "fmt"
        "encoding/json"
    )
    
    type Session struct {
        Name            string           `json:"name,omitempty"`
        SharedItems     []SharedItem    `json:"shared_items"`
    }
    
    type SharedItem struct {
        ID          uint64 `json:"id"`
        Name        string `json:"name"`
    }
    
    const myStr = `{"name":"test_session1","shared_items":[{"id":0,"name":".aspnet"},{"id":1,"name":".bash_profile"}]}`
    
    func main() {
        var sess Session
    
        if err := json.Unmarshal([]byte(myStr), &sess); err != nil {
            panic(err)
        }
        fmt.Println(sess)
        fmt.Printf("sess name is: %s, and has %d shared items
    ", sess.Name, len(sess.SharedItems))
    }
    

    Playground example

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 matlab实现基于主成分变换的图像融合。
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊