只要我有键-值对,解组就非常简单,但是如何解组不同顺序的不同类型的数组呢?单个元素被很好地定义和知道,但是顺序不是很清楚.

我想不出一个好的解决方案.

我会try 在所有元素上出错吗?

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的很好的文章.可以将任意数据"解码"到接口{}中,并使用类型断言动态确定类型.

您的代码可能会修改为:

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"

它还没有完成,但展示了它将如何工作.

Go相关问答推荐

为什么(编码器).EncodeElement忽略";,innerxml";标记?

租户GUID X的租户不存在self 邮箱帐户的租户(我是唯一的成员)

在Golang中Mergesort的递归/并行实现中出现死锁

埃拉托塞尼筛:加快交叉关闭倍数步骤

Go中的Slice[:1][0]与Slice[0]

从使用Golang otelmux检测的Otel跟踪中获取trace_id

显示GUI时后台处理功能

JWT 如何解析声明有效性和错误?

不接受来自 stdin 的重复输入

生成一个 CSV/Excel,在 Golang 中该列的下拉选项中指定值

如何从 Go 中的 `HijackedResponse` 中删除 Cursor Position ANSI 转义码?

golang 中的可变参数函数

Protobuf.Any - 从 json.RawMessage 解组

在 GORM 中,如何在特定时区配置 autoCreateTime 和 autoUpdateTime?

try 与 golang testify/suite 并行运行测试失败

没有堆栈跟踪的 go 程序崩溃是什么意思?

使用无服务器工作流 go sdk 时出现间歇性 JSON 解组错误

自定义指标未显示在 prometheus web ui 中,grafana 中也是如此

将 Simple Go Web 应用程序部署到 Elastic Beanstalk

即使没有竞争条件也没有得到任何输出