在 Go 中解组 JSON 数组
Unmarshal JSON Array in Go
我在这里阅读了一些答案,none 似乎有所帮助。我一直收到同样的错误:
json: cannot unmarshal array into Go value of type A
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
}
json 看起来像这样:
[
["Name", "Another Name", "Another"],
["A", "B"],
["W", "X", "Y", "Z"],
["Foo", "Bar"]
]
我在搜索时尝试了各种不同的最佳答案,但如前所述,没有任何效果。
我对 Go 还是相当陌生,不得不解组(我目前正在解组 [][]string
但我想使用结构)。我做错了什么?
一个结构有字段;字段有名称;结构中字段的名称是 Arr
。因此,json 输入需要是 [{ "arr": ["list", "of", "names"]}, {"arr": ["more", "names"]}]
,例如,给定上面的示例。
但是,您可以在名为 A
的 type 上定义一个 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
}
这个名为 UnmarshalJSON
的接收函数接受一个指向 A
对象的指针,加上某种有效的 json 输入。它的工作是解组 json。在这种情况下,我们尝试解组为一个普通的 slice-of-string
——变量 s
——只要 json 本身 是 slice-of-strings.
的有效初始值设定项
如果解组成功,我们然后设置 p.Arr
,知道数组仅用于名为 Arr
的东西(实际上它是结构类型的唯一成员)和 return nil
(没有错误).
注意最后几行可以写成:
if err == nil {
p.Arr = s
}
return err
这更短,但 Go 约定通常首先处理错误情况,而不是让它流过。 (实际上,我自己更喜欢较短的代码,但可以使用您的小组喜欢的任何代码。)
(给定类型上的 UnmarshalJSON
接收器,类型上可能也应该有一个 json 编组器,但我的最小 test-and-example on the Go playground 没有。)
您的 json 内容应该是这样的
[
{
"Arr": [
"a0",
"a1"
]
},
{
"Arr": [
"b0",
"b1"
]
},
{
"Arr": [
"c0",
"c1"
]
}
]
我在这里阅读了一些答案,none 似乎有所帮助。我一直收到同样的错误:
json: cannot unmarshal array into Go value of type A
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
}
json 看起来像这样:
[
["Name", "Another Name", "Another"],
["A", "B"],
["W", "X", "Y", "Z"],
["Foo", "Bar"]
]
我在搜索时尝试了各种不同的最佳答案,但如前所述,没有任何效果。
我对 Go 还是相当陌生,不得不解组(我目前正在解组 [][]string
但我想使用结构)。我做错了什么?
一个结构有字段;字段有名称;结构中字段的名称是 Arr
。因此,json 输入需要是 [{ "arr": ["list", "of", "names"]}, {"arr": ["more", "names"]}]
,例如,给定上面的示例。
但是,您可以在名为 A
的 type 上定义一个 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
}
这个名为 UnmarshalJSON
的接收函数接受一个指向 A
对象的指针,加上某种有效的 json 输入。它的工作是解组 json。在这种情况下,我们尝试解组为一个普通的 slice-of-string
——变量 s
——只要 json 本身 是 slice-of-strings.
如果解组成功,我们然后设置 p.Arr
,知道数组仅用于名为 Arr
的东西(实际上它是结构类型的唯一成员)和 return nil
(没有错误).
注意最后几行可以写成:
if err == nil {
p.Arr = s
}
return err
这更短,但 Go 约定通常首先处理错误情况,而不是让它流过。 (实际上,我自己更喜欢较短的代码,但可以使用您的小组喜欢的任何代码。)
(给定类型上的 UnmarshalJSON
接收器,类型上可能也应该有一个 json 编组器,但我的最小 test-and-example on the Go playground 没有。)
您的 json 内容应该是这样的
[
{
"Arr": [
"a0",
"a1"
]
},
{
"Arr": [
"b0",
"b1"
]
},
{
"Arr": [
"c0",
"c1"
]
}
]