如何正确解组一个不同类型的数组? [英] How to unmarshall an array of different types correctly?
问题描述
只要我有键值对,unmarshalling是非常直接的,但我将如何以不同顺序解组一个不同类型的数组?单个元素已被很好地定义并且已知,但命令不是。
我无法想出一个漂亮的解决方案。
我会尝试所有元素的错误吗?
是否有某种类型的工会可以为我做这件事?
包主
导入(
encoding / json
fmt
)
var my_json string =`{
an_array:[
with_a字符串,
{
和:some_more,
different:[嵌套,类型]
}
]
类型MyInner结构{
和字符串
不同[]字符串
}
类型MyJSON结构{
An_array [] json.RawMessage
}
func main(){
var my_json_test MyJSON
e:= json.Unmarshal([] byte(my_json ),& my_json_test)
if e!= nil {
fmt.Println(e)
} else {
for index,value:= range my_json_test.An_array {
fmt.Println(index:,index)
fmt.Print ln(value:,string(value))
}
var my_inner MyInner
err:= json.Unmarshal(my_json_test.An_array [1],& my_inner)
if err!= nil {
fmt.Println(err)
} else {
fmt.Println(inner structure:,my_inner)
}
}
Go官方博客有一篇不错的文章关于 encoding / json
: JSON和GO 。可以将解码任意数据插入到接口中,并使用类型断言来动态确定类型。
您的代码可能会被修改为:
package main
import(
encoding / json
fmt
var my_json string =`{
an_array:[
with_a string,
{
and: some_more,
different:[nested,types]
}
]
}`
func WTHisThisJSON(f interface { }){
switch vf:= f。(type){
case map [string] interface {}:
fmt.Println(is a map:)
for k,v:=范围vf {
switch vv:= v。(type){
case string:
fmt.Printf(%v:is string - %q \\\
,k,vv)
case int:
fmt.Printf(%v:is int - %q\\\
,k,vv)
默认值:
fmt。 Printf(%v:,k)
WTHisThisJSON(v)
}
}
case [] interface {}:
fmt.Println(是一个数组:)
for k ,v:= range vf {
switch vv:= v。(type){
case string:
fmt.Printf(%v:is string - %q \\\
, k,vv)
case int:
fmt.Printf(%v:is int - %q\\\
,k,vv)
默认值:
fmt.Printf (%v:,k)
WTHisThisJSON(v)
}
}
}
}
func main(){
fmt.Println(JSON:\ n,my_json,\\\
)
var f interface {}
err := json.Unmarshal([] byte(my_json),& f)
if err!= nil {
fmt.Println(err)
} else {
fmt。 Printf(JSON:)
WTHisThisJSON(f)
}
}
它给出如下输出:
JSON:
{
an_array:[
with_a string,
{
和:some_more,
different:[nested,types]]
$ b JSON:是一个映射:
an_array:是一个数组:
0:是字符串 - with_a字符串
1:是地图:
和:是字符串 - some_more
不同:是一个数组:
0:是字符串 - 嵌套
1:是字符串 - 类型
目前还不完整,但显示了它将如何工作。 / p>
As long as I have key-value pairs unmarshalling is pretty straight forward but how would I unmarshall an array of different types in different order? The single elements are well defined and known but the order is not.
I can not come up with a beautiful solution.
Would I try and error over all elements? Is there some kind of union type that could do that for me?
package main
import (
"encoding/json"
"fmt"
)
var my_json string = `{
"an_array":[
"with_a string",
{
"and":"some_more",
"different":["nested", "types"]
}
]
}`
type MyInner struct {
And string
Different []string
}
type MyJSON struct {
An_array []json.RawMessage
}
func main() {
var my_json_test MyJSON
e := json.Unmarshal([]byte(my_json), &my_json_test)
if e != nil {
fmt.Println(e)
} else {
for index, value := range my_json_test.An_array {
fmt.Println("index: ", index)
fmt.Println("value: ", string(value))
}
var my_inner MyInner
err := json.Unmarshal(my_json_test.An_array[1], &my_inner)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("inner structure: ", my_inner)
}
}
}
Go official blog has a nice article about encoding/json
: JSON and GO. It's possible to "Decode arbitrary data" into an interface{} and use type assertion to determine the type dynamically.
Your code can be probably modified to this:
package main
import (
"encoding/json"
"fmt"
)
var my_json string = `{
"an_array":[
"with_a string",
{
"and":"some_more",
"different":["nested", "types"]
}
]
}`
func WTHisThisJSON(f interface{}) {
switch vf := f.(type) {
case map[string]interface{}:
fmt.Println("is a map:")
for k, v := range vf {
switch vv := v.(type) {
case string:
fmt.Printf("%v: is string - %q\n", k, vv)
case int:
fmt.Printf("%v: is int - %q\n", k, vv)
default:
fmt.Printf("%v: ", k)
WTHisThisJSON(v)
}
}
case []interface{}:
fmt.Println("is an array:")
for k, v := range vf {
switch vv := v.(type) {
case string:
fmt.Printf("%v: is string - %q\n", k, vv)
case int:
fmt.Printf("%v: is int - %q\n", k, vv)
default:
fmt.Printf("%v: ", k)
WTHisThisJSON(v)
}
}
}
}
func main() {
fmt.Println("JSON:\n", my_json, "\n")
var f interface{}
err := json.Unmarshal([]byte(my_json), &f)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("JSON: ")
WTHisThisJSON(f)
}
}
It gives output as follows:
JSON:
{
"an_array":[
"with_a string",
{
"and":"some_more",
"different":["nested", "types"]
}
]
}
JSON: is a map:
an_array: is an array:
0: is string - "with_a string"
1: is a map:
and: is string - "some_more"
different: is an array:
0: is string - "nested"
1: is string - "types"
It's not complete yet, but shows how it's gonna work.
这篇关于如何正确解组一个不同类型的数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!