在 Golang 中动态解组 JSON 的最有效方法 [重复]

     2023-02-15     247

关键词:

【中文标题】在 Golang 中动态解组 JSON 的最有效方法 [重复]【英文标题】:Most efficient way to dynamically unmarshall JSON in Golang [duplicate] 【发布时间】:2022-01-21 12:30:34 【问题描述】:

使用 Golang,我需要解组具有有限数量结构和公共头部的嵌套 JSON 消息。头部包含类型信息,用于标识 JSON 消息包含的详细结构。我尝试做的是从头部提取类型信息,然后动态选择结构的细节。程式化的 JSON 字符串示例如下所示:

"type":"a_number", "data":"somenumber":1234
"type":"b_string", "data":"somestring":"a string", "anotherstring": "a second string"`

我最初的方法是使用如下结构:

type Head struct 
    Type  string `json:"type"`
    Data interface `json:"data"`


type A struct 
    SomeNumber decimal.Decimal `json:"somenumber"`


type B struct 
    SomeString string `json:"somestring"`
    AnotherString string `json:"anotherstring"`

我尝试在数据元素上使用 interface.(type) 来检查适用的结构,如下所示:

var msg Head

json.Unmarshal([]byte(jsonString), &msg)

switch v := msg.Data.(type) 
    case A:
        fmt.Printf("Type is A (%v)", v)
        detail := msg.Data.(A)
        fmt.Println(detail.SomeNumber)
    case B:
        fmt.Printf("Type is B (%v)", v)
        detail := msg.Data.(B)
        fmt.Println(detail.SomeString)
    default:
        fmt.Printf("I don't know about type %T!\n", v)

这显然不起作用,因为msgmap[string]interface 类型。我的下一个尝试是使用类似的东西:

data := msg.Data.(map[string]interface )

v ,exist := data["somestring"]
if exist 
    fmt.Println("somestring: ",v)

这在这个简单的例子中是可行的并且是可以的,但在实际的例子中,有很多超过 2 个结构,它们本身是嵌套的并且相当复杂。

我设法找到的唯一方法是创建多个特定结构并使用多个这样的解组:

type GenericHead struct 
    Type  string `json:"type"`
    Data interface `json:"data"`


type A struct 
    SomeNumber decimal.Decimal `json:"somenumber"`


type B struct 
    SomeString string `json:"somestring"`
    AnotherString string `json:"anotherstring"`


type SpecificA struct 
    Type  string `json:"type"`
    Data A `json:"data"`


type SpecificB struct 
    Type  string `json:"type"`
    Data B `json:"data"`

然后

var msg Head

json.Unmarshal([]byte(jsonString), &msg)

if msg.Type == "a_number" 
   var data SpecificA
   json.Unmarshal([]byte(jsonString), &data)
 else 
   var data SpecificA
   json.Unmarshal([]byte(jsonString), &data)

必须定义多个(冗余)结构并多次解组似乎非常低效且不必要地复杂。

解决这种情况的更有效的“最佳实践”方法是什么?

【问题讨论】:

Decoding generic JSON objects to one of many formats 回答你的问题了吗? 这就是我想要的。谢谢 Cerise! 【参考方案1】:

感谢 Cerise Limón 的指示,Decoding generic JSON objects to one of many formats 中已经提供了答案,并使用 json.RawMessage 作为解决方案:

type Head struct 
    Type  string `json:"type"`
    Data json.RawMessage `json:"data"`

var msg Head

json.Unmarshal([]byte(jsonString), &msg)

switch msg.Type 
    case "a_number":
        var detail A
        json.Unmarshal([]byte(msg.Data),&detail)
        fmt.Println(detail.SomeNumber)
    case "b_string":
        var detail B
        json.Unmarshal([]byte(msg.Data),&detail)
        fmt.Println(detail.SomeString)
    default:
        fmt.Printf("I don't know about type %s!\n",  msg.Type)

【讨论】:

Golang Json 使用多个动态命名字段解组

】GolangJson使用多个动态命名字段解组【英文标题】:GolangJsonunmarshalingwithmultipledynamicallynamedfields【发布时间】:2021-07-1102:04:09【问题描述】:我有以下需要解码的Json结构,但我不确定正确的方法用于解组它。varb=[]byte(`"Card:5417871... 查看详情

在 Golang 中解组 XML 时如何在 interface 中获取数据?

】在Golang中解组XML时如何在interface中获取数据?【英文标题】:howtogetdataininterfacewhileunmarshalinganXMLinGolang?在Golang中解组XML时如何在interface中获取数据?【发布时间】:2014-05-1412:08:28【问题描述】:我正在尝试在golang中使用interface... 查看详情

当 JSON 字段键是日期时,如何将 JSON 对象解组为 Golang 结构?

】当JSON字段键是日期时,如何将JSON对象解组为Golang结构?【英文标题】:HowdoyouunmarshalaJSONobjecttoaGolangstructwhentheJSONfieldkeyisadate?【发布时间】:2021-09-2123:39:49【问题描述】:我有以下JSON响应。将其解组为Golang结构的最佳方法是... 查看详情

golang中的动态嵌套结构

】golang中的动态嵌套结构【英文标题】:Dynamicnestedstructingolang【发布时间】:2021-08-0800:29:53【问题描述】:我想创建一个动态结构。我正在使用一些命令来获取一些JSON格式的信息,并希望将其解组为一个结构。Json看起来像这样... 查看详情

在内存中操作 std::strings 的 2D 动态数组的最有效方法是啥?

】在内存中操作std::strings的2D动态数组的最有效方法是啥?【英文标题】:Whatisthemostefficientwaytomanipulatea2Ddynamicarrayofstd::stringsinmemory?在内存中操作std::strings的2D动态数组的最有效方法是什么?【发布时间】:2011-08-0301:10:10【问题... 查看详情

在正则表达式 C# 中转换 json 的最有效方法

】在正则表达式C#中转换json的最有效方法【英文标题】:MostefficientwaytoconvertjsoninregexC#【发布时间】:2016-09-0203:10:51【问题描述】:json:["Command":"Notificaion-:hi","ID":"142245","AnotherColumn":"data1","Command":"Notificaion-:hi2","ID":"14255","Anothe 查看详情

在 Obj-C 中动态进行 segue 的最有效方法?

】在Obj-C中动态进行segue的最有效方法?【英文标题】:MostefficientwaytodynamicallymakeasegueinObj-C?【发布时间】:2018-10-0314:24:02【问题描述】:我正在为我的应用程序编写一个segue。基本上,当按下UITableViewCell中的附件时,应该调用这... 查看详情

在不知道结构的情况下解组嵌套的 json

...:2015-08-1422:28:13【问题描述】:我使用键值存储作为我的golang应用程序的后端,日期作为键(以保持条目排序),json文档作为值。我存储的每个json文档中都存在json(foo)和type和date的***命名空间,但在其他方面存在一些差异(尤... 查看详情

在spring mvc应用程序中加密json有效负载的最早点

】在springmvc应用程序中加密json有效负载的最早点【英文标题】:Earliestpointtoencryptjsonpayloadinspringmvcapplication【发布时间】:2020-01-0500:48:58【问题描述】:我有一个SpringBoot应用程序服务于restfulapi。我想确保尽早屏蔽/加密某些字段... 查看详情

解析 JSON 对象的最有效方法 [重复]

】解析JSON对象的最有效方法[重复]【英文标题】:MosteffectivewaytoparseJSONObjects[duplicate]【发布时间】:2021-08-2012:27:01【问题描述】:我目前正在尝试访问JSON对象中的特定值,我正在使用Try/except语句成功地做到这一点。由于我还在... 查看详情

在 Golang 中将字符串解组为类似结构的结构

】在Golang中将字符串解组为类似结构的结构【英文标题】:UnmarshalingstringtostructlikestructureinGolang【发布时间】:2021-08-2900:49:27【问题描述】:Golang给了我一个字符串:varcars=[model:"SLR",brand:"Mercedes",prices:[520,730],,model:"M4",brand:"BMW",pri... 查看详情

(预)处理存储在 json 中的大型数据集的最有效方法是啥?

】(预)处理存储在json中的大型数据集的最有效方法是啥?【英文标题】:Whatisthemostefficientwayto(pre)processlargedatasetsstoredinjson?(预)处理存储在json中的大型数据集的最有效方法是什么?【发布时间】:2020-09-2722:29:03【问题描述... 查看详情

json:无法将字符串解组为 MyMap.map 类型的 Go 值

...【发布时间】:2022-01-1214:14:40【问题描述】:我遇到了在golang中编组JSON的问题。我需要解组从UDP数据包收到的json对象。但我遇到了解组的问题-它不想正确解组。我收到“解组错误:json:无法将字符串解组为main.MyMap类型的 查看详情

如何在单个路由中解组 POST 参数和 JSON 正文?

】如何在单个路由中解组POST参数和JSON正文?【英文标题】:HowtounmarshalPOSTparamsandJSONbodyinasingleroute?【发布时间】:2015-02-2618:03:56【问题描述】:我有这条路线:valroutes=pathPrefix("api")path("ElevationService"/DoubleNumber/DoubleNumber)(long,lat)=&... 查看详情

嵌入式结构的多态 JSON 解组

...-06-0601:34:39【问题描述】:这是一个例子(另见https://play.golang.org/p/or7z4Xc8tN):packagemainimport("encoding/json""fmt")typeAstructXstringYinttypeBstructAY 查看详情

GOlang XML 解析/解组

】GOlangXML解析/解组【英文标题】:GOlangXMLparsing/unmarshal【发布时间】:2016-08-1723:02:33【问题描述】:我在Go中解析xml时遇到问题。任何人都可以帮忙吗?XML格式为:<Feedversion=\'1.03\'format=\'FULL\'date=\'2016-04-22T18:31:01.4988282+01:00\'>... 查看详情

GAE Golang - HTTP JSON RPC 调用在 dev_appserver 中有效,但在 App Engine 上无效?

】GAEGolang-HTTPJSONRPC调用在dev_appserver中有效,但在AppEngine上无效?【英文标题】:GAEGolang-HTTPJSONRPCcallworksinthedev_appserver,butnotontheAppEngine?【发布时间】:2012-01-3104:24:53【问题描述】:我正在创建一个GoGoogleAppEngine应用程序,它将对Bi... 查看详情

如何在 ApiController 的 json 有效负载中拥有一种动态字段?

】如何在ApiController的json有效负载中拥有一种动态字段?【英文标题】:HowtohaveakindofdynamicfieldinsidethejsonpayloadonaApiController?【发布时间】:2022-01-1215:53:31【问题描述】:我需要json架构的一部分是可变的。如何声明将绑定到json的动... 查看详情