json - 如何正确解码不同类型的数组?

标签 json go unmarshalling

只要我有键值对,解码非常简单,但我如何以不同的顺序解码不同类型的数组?单个元素定义明确且已知,但顺序不明确。

我想不出一个漂亮的解决方案。

我会尝试在所有元素上出错吗? 是否有某种联合类型可以为我做到这一点?

playground version

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 官方博客有一篇关于 encoding/json 的好文章: JSON and GO .可以将任意数据“解码”到接口(interface)中{},并使用类型断言来动态确定类型。

你的代码大概可以修改成这样:

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)
    }
}

输出如下:

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"

它还没有完成,但展示了它是如何工作的。

关于json - 如何正确解码不同类型的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13364181/

相关文章:

javascript - 如何在 Extjs 中将数据从 Json 加载到 Json

json - 将 pcap 转换为 JSON 的最简单方法

go - 在结构中使用 map 的更好方法? Go编程语言练习1.4

java - JAXB un/marshalling : Is there a difference between using arrays and lists?

c# - 字符串的长度超过了 maxJsonLength 属性上设置的值

javascript - 从 REST 服务器和 Coffeescript 前端开始

go - 带 channel 的 WaitGroup goroutines

concurrency - 比较 2 张 map 的元素 - 我这样做对吗?

json - 为什么编码(marshal)无法使用嵌套结构?

对于 Golang 中的数组,XML Unmarshalling 属性不同