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

时间:2018-04-26 05:31:20

标签: arrays json go struct unmarshalling

当对象具有嵌套的struct对象数组时,我遇到了一些问题,即将字符串解组回struct对象。我使用以下代码作为我的问题的演示:

json字符串是

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

我有两个结构如下,其中会话是父级, SharedItem 是关联子级(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"`
}

我尝试了以下内容来解组json字符串,但看起来缺少 SharedItem 对象的嵌套数组,因为我看到 sess 对象有 0 共享项目,这不是我的预期。

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\n", sess.Name, len(sess.SharedItems)) // printed: sess name is test_session1, and has 0 shared items
}

这是我去游乐场的链接:https://play.golang.org/p/a-y5T3tut6g

1 个答案:

答案 0 :(得分:3)

json unmarshal的Golang Spec描述了这一切

  

要将JSON解组为结构,Unmarshal匹配传入的对象   Marshal使用的键的键(结构字段名称或其字符串)   标签),更喜欢完全匹配,但也接受不区分大小写   比赛。默认情况下,没有相应结构的对象键   字段被忽略(请参阅Decoder.DisallowUnknownFields   替代)。

在json中,共享项的json对象中包含:冒号,因为我们可以看到它是shared_items:而不是shared_items这是我们的json标记

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

删除:或附加到struct json标记以匹配相同的内容。

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\n", sess.Name, len(sess.SharedItems))
}

Playground example