json - 你如何在 Golang 中修改这个结构来接受两个不同的结果?

标签 json go struct dynamic

对于以下 JSON 响应 {"table_contents":[{"id":100,"description":"text100"},{"id":101,"description":"text101"},{"id":1,"description":"text1"}]}您所要做的就是生成以下代码以正确执行它并能够从结构中读取字段,例如:

package main

import (
    "fmt"
    "encoding/json"
)

type MyStruct1 struct {
    TableContents []struct {
        ID          int
        Description string
    } `json:"table_contents"`
}

func main() {
    result:= []byte(`{"table_contents":[{"id":100,"description":"text100"},{"id":101,"description":"text101"},{"id":1,"description":"text1"}]}`)
    var container MyStruct1
    err := json.Unmarshal(result, &container)
    if err != nil {
        fmt.Println(" [0] Error message: " + err.Error())
        return
    }
    
    for i := range container.TableContents {
        fmt.Println(container.TableContents[i].Description)
    }
    
}
但是你如何处理下面的 JSON 响应呢? {"table_contents":[[{"id":100,"description":"text100"},{"id":101,"description":"text101"}],{"id":1,"description":"text1"}]}您可以获得此响应或上述响应,重要的是修改结构以接受两者。
在互联网的帮助下,我做了这样的事情:
package main

import (
    "fmt"
    "encoding/json"
)

type MyStruct1 struct {
    TableContents []TableContentUnion `json:"table_contents"`
}

type TableContentClass struct {
    ID          int        
    Description string
}

type TableContentUnion struct {
    TableContentClass      *TableContentClass
    TableContentClassArray []TableContentClass
}

func main() {
    result:= []byte(`{"table_contents":[[{"id":100,"description":"text100"},{"id":101,"description":"text101"}],{"id":1,"description":"text1"}]}`)
    var container MyStruct1
    err := json.Unmarshal(result, &container)
    if err != nil {
        fmt.Println(" [0] Error message: " + err.Error())
        return
    }
    
    for i := range container.TableContents {
        fmt.Println(container.TableContents[i])
    }
    
}
但它不会超过错误消息:(
  • [0] 错误消息:json: cannot unmarshal array into Go struct field MyStruct1.table_contents of type main.TableContentUnion*

  • 几个小时以来一直在努力想出一个解决方案。如果有人可以帮助我会很高兴。感谢您的阅读。如果您有任何问题,请告诉我

    最佳答案

    内部 table_contents您有两种类型选项(json 对象或 json 对象列表)。您可以做的是解码到一个接口(interface),然后在使用它时对其运行类型检查:

    type MyStruct1 struct {
        TableContents []interface{} `json:"table_contents"`
    }
    
    ...
    
    for i := range container.TableContents {
        switch container.TableContents[i].(type){
        case map[string]interface{}:
            fmt.Println("json object")
        case []interface{}:
            fmt.Println("list")
        }
    }
    
    
    从那里您可以使用一些库(例如 https://github.com/mitchellh/mapstructure )将未编码的结构映射到您的 TableContentClass类型。在此处查看 PoC 游乐场:https://play.golang.org/p/NhVUhQayeL_C

    关于json - 你如何在 Golang 中修改这个结构来接受两个不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63727028/

    相关文章:

    sql - PostgreSQL:有效地将 JSON 数组拆分为行

    debugging - 如何在传递参数时在调试器中运行 Go 二进制文件?

    arrays - 包含指向结构的指针的深度复制映射

    go - 从本地子目录导入包

    c - 为什么 typedef 名称在 C 的结构声明中使用了两次?

    c - 将数据动态添加到指向函数内结构的指针数组

    javascript - 如何将 JSON 值从 Controller 传递到 Thymeleaf 中的 HTML?

    arrays - 从 NodeJS 中的复杂 JSON 字符串获取值

    go - 如何通过字符串名称和字符串结构名称调用方法?

    python - Django 继承模型的 JSON 序列化