英文:
How can I turn map[string]interface{} to different type of struct?
问题
我正在调用一个API,它将返回如下的JSON对象:
{
"name": "XXX",
"type": "TYPE_1",
"shared_fields": {...},
"type_1_fields": {...},
..
"type_2_fields": {...}
}
根据不同的类型,这个对象将具有不同类型的字段,但这些字段对于不同的类型是确定的。
因此,我将JSON字符串解组为map[string]interface{}
以获取不同的类型,但是如何将这些map[string]interface{}
转换为特定的结构体呢?
var f map[string]interface{}
err := json.Unmarshal(b, &f)
type := f["type"]
switch type {
case "type_1":
//初始化type_1的结构体
case "type_2":
//初始化type_2的结构体
}
英文:
I'm calling an API which will return Json objects like this:
{
name: "XXX"
type: "TYPE_1"
shared_fields: {...}
type_1_fields: {...}
..
type_2_fields: {...}
}
Based on different types, this object will have different kinds of fields, but these fields are certain for different types.
So, I unmarshal the Json string to map[string]interface{} to fetch the the different type but how can I turn these map[string]interface{} to a certain struct?
var f map[string]interface{}
err := json.Unmarshal(b, &f)
type := f["type"]
switch type {
case "type_1":
//initialize struct of type_1
case "type_2":
//initialize struct of type_2
}
答案1
得分: 2
对于这种两步骤的 JSON 解码,你可能想要查看 json.RawMessage。它允许你推迟处理 JSON 响应的某些部分。文档中的示例展示了如何使用它。
英文:
For this sort of two-step json decoding you will probably want to check out json.RawMessage. It allows you to defer processing of parts of your json response. The example in the docs shows how.
答案2
得分: 0
一种方法是使用一个构造函数(以New…
开头)作为输入参数来接收一个映射。
第二种方法,我认为速度较慢,是重新将其解组为正确的结构类型。
英文:
One way to do it would be to have a constructor function (one that starts with New…
) that takes a map as input parameter.
A second way, much slower in my opinion, would be to redo the unmarshalling to the right struct type.
答案3
得分: 0
如果类型差异很大,并且你想要懒一点,你可以尝试在每种格式中进行解码:
f1 := type1{}
err := json.Unmarshal(b, &f1)
if err == nil {
return f1
}
f2 := type2{}
err := json.Unmarshal(b, &f2)
if err == nil {
return f2
}
...
如果对象相似或者你想要更加细致,你可以先解码类型,然后再进行操作:
type BasicInfo struct {
Type string `json:"type"`
}
f := BasicInfo{}
err := json.Unmarshal(b, &f)
switch f.Type {
case "type_1":
//初始化 type_1 的结构体
case "type_2":
//初始化 type_2 的结构体
}
英文:
If the types are different enough and you want to be lazy you can just try to decode it in each format:
f1 := type1{}
err := json.Unmarshal(b, &f1)
if err == nil {
return f1
}
f2 := type2{}
err := json.Unmarshal(b, &f2)
if err == nil {
return f2
}
...
If the objects are similar or you want to be less lazy, you could just decode the type and then do something:
type BasicInfo struct {
Type string `json:"type"`
}
f := BasicInfo{}
err := json.Unmarshal(b, &f)
switch f.Type {
case "type_1":
//initialize struct of type_1
case "type_2":
//initialize struct of type_2
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论