简体   繁体   English

在 Go 中解组 JSON 数组

[英]Unmarshal JSON Array in Go

I've read a few answers here and none seem to help.我在这里阅读了一些答案,但似乎没有任何帮助。 I keep getting the same error:我不断收到同样的错误:

json: cannot unmarshal array into Go value of type A json:无法将数组解组为 A 类型的 Go 值

type A struct {
    Arr []string
}

type MA []A
func UnmarshalJSON() (ma MA, err error) {
    jsonFile, err := os.Open(aJsonFile)
    // error handling
    defer jsonFile.Close()
    byteValue, _ := ioutil.ReadAll(jsonFile)
    err = json.Unmarshal(byteValue, &ma)
    if err != nil {
        return ma, err
    }
    return ma, nil
}

The json looks like this: json 看起来像这样:

[
  ["Name", "Another Name", "Another"],
  ["A", "B"],
  ["W", "X", "Y", "Z"],
  ["Foo", "Bar"]
]

I've tried various different things from top answers when searching and as previously stated, nothing has worked.我在搜索时尝试了各种不同的方法,如前所述,没有任何效果。

I'm still decently new to Go and having to unmarshall stuff (I'm currently unmarshalling to [][]string but I want to use structs).我对 Go 仍然很陌生,并且不得不解组东西(我目前正在解组到[][]string ,但我想使用结构)。 What am I doing wrong?我究竟做错了什么?

A struct has fields;结构有字段; fields have names;字段有名称; the name of the field in your struct is Arr .结构中字段的名称是Arr So the json input would need to be [{ "arr": ["list", "of", "names"]}, {"arr": ["more", "names"]}] for instance, given the example you have above.所以 json 输入需要是[{ "arr": ["list", "of", "names"]}, {"arr": ["more", "names"]}]例如,给定你上面的例子。

You can, however, define an UnmarshalJSON on your type named A , like this:但是,您可以在名为A类型上定义 UnmarshalJSON,如下所示:

func (p *A) UnmarshalJSON(data []byte) error {
    var s []string
    err := json.Unmarshal(data, &s)
    if err != nil {
        return err
    }
    p.Arr = s
    return nil
}

This receiver function named UnmarshalJSON takes a pointer to an A object, plus some sort of valid json input.这个名为UnmarshalJSON的接收器 function 采用指向A object 的指针,以及某种有效的 json 输入。 Its job is to unmarshal that json.它的工作是解组 json。 In this case we attempt to unmarshal into an ordinary slice-of- string —the variable s —which works as long as the json itself is a valid initializer for slice-of-strings.在这种情况下,我们尝试解组为一个普通的string切片——变量s只要 json 本身字符串切片的有效初始化程序,它就可以工作。

If the unmarshal succeeds we then set p.Arr , knowing that the array is meant just for the thing named Arr (which is in fact the only member of the structure type) and return nil (no error).如果解组成功,我们将设置p.Arr ,知道该数组仅用于名为Arr的事物(实际上是结构类型的唯一成员)并返回nil (无错误)。

Note that the last few lines could be written as:注意最后几行可以写成:

if err == nil {
    p.Arr = s
}
return err

which is shorter, but Go conventions generally handle the error case first, rather than letting it flow through.这更短,但 Go 约定通常首先处理错误情况,而不是让它通过。 (I actually prefer the shorter code myself, slightly, but use whatever your group likes.) (实际上,我自己更喜欢较短的代码,但请使用您的团队喜欢的任何代码。)

(Given an UnmarshalJSON receiver on the type, there probably should be a json marshaler on the type, too, but my minimal test-and-example on the Go playground does not have one.) (给定类型上的UnmarshalJSON接收器,该类型上可能也应该有一个 json 编组器,但我在 Go 操场上的最小测试和示例没有。)

your json content should like this您的 json 内容应该是这样的

[
    {
        "Arr": [
            "a0",
            "a1"
        ]
    },
    {
        "Arr": [
            "b0",
            "b1"
        ]
    },
    {
        "Arr": [
            "c0",
            "c1"
        ]
    }
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM