3 回答
TA贡献1820条经验 获得超2个赞
您指定的 JSON 输入是不同类型的数组,因此,您无法将其解组为struct,而只能解组为不同类型的切片:[]interface{}。
in := `["contig", "32", {"a":[33,41,35], "b":[44,34,42]}]`
var arr []interface{}
if err := json.Unmarshal([]byte(in), &arr); err != nil {
panic(err)
}
fmt.Println(arr)
输出:
[contig 32 map[a:[33 41 35] b:[44 34 42]]]
填写 struct
很好,你现在拥有了价值观,只是不在struct你想要的。您可以使用类型断言来获取您想要的类型:
l := Line{PopMap: map[string][]int{}}
l.Contig = arr[0].(string)
l.Base = arr[1].(string)
m := arr[2].(map[string]interface{})
for k, v := range m {
nums := v.([]interface{})
pops := make([]int, len(nums))
for i, val := range nums {
pops[i] = int(val.(float64))
}
l.PopMap[k] = pops
}
fmt.Printf("%+v", l)
输出(在Go Playground上试试):
{Contig:contig Base:32 PopMap:map[a:[33 41 35] b:[44 34 42]]}
一些注意事项:
值的“内部”阵列"a"和"b"被解组到类型的值[]interface{},你不能简单地转换为[]int或[]float64将因此for循环遍历它们和使用类型断言每个自己的元素。另请注意,该json包将数字解组为 typefloat64和 not类型的值int(因为 JSON 文本中不仅可以包含整数,因此float64可以同时使用两者)。
还要注意,在上面的例子中没有检查类型断言是否成功。如果解组的数组少于 3 个元素,或者任何类型断言失败,都会发生运行时恐慌。
使用 recover()
您可以添加一个defer函数来调用recover()以捕获此恐慌(在Go Playground上尝试):
defer func() {
if r := recover(); r != nil {
fmt.Println("Failed to unmarshal")
}
}()
l := Line{PopMap: map[string][]int{}}
// ...and here comes the code that uses type assertions
// and stores values into...
带检查的代码
或者您可以添加对类型断言的检查。类型断言有一种特殊的形式v, ok = x.(T),在使用时不会发生恐慌,而是如果类型断言不成立,ok将会是false(true如果类型断言成立,将会是)。
在Go Playground上试试:
if len(arr) < 3 {
return
}
var ok bool
l := Line{PopMap: map[string][]int{}}
if l.Contig, ok = arr[0].(string); !ok {
return
}
if l.Base, ok = arr[1].(string); !ok {
return
}
if m, ok := arr[2].(map[string]interface{}); !ok {
return
} else {
for k, v := range m {
var nums []interface{}
if nums, ok = v.([]interface{}); !ok {
return
}
pops := make([]int, len(nums))
for i, val := range nums {
if f, ok := val.(float64); !ok {
return
} else {
pops[i] = int(f)
}
}
l.PopMap[k] = pops
}
}
fmt.Printf("%+v", l)
TA贡献1772条经验 获得超8个赞
您的 JSON 包含一个数组文字,您正试图将其反序列化为一个结构体。您需要将 JSON 更改为对象文字,其中键是结构的属性名称。
j := []byte(`{
"Contig": "contig",
"Base": "32",
"PopMap": {"a":[33,41,35], "b":[44,34,42]}
}`)
如果 JSON 不是您有能力更改的东西,那么您需要将其反序列化为一个无类型数组,并执行您自己到结构类型的转换。
- 3 回答
- 0 关注
- 286 浏览
添加回答
举报