将JSON解组为struct

时间:2017-11-01 09:14:50

标签: go

当在JSON字符串中给出结构类型时,如何将JSON字符串解组成结构。这是我的代码:

package main

import (
    "fmt"
    "encoding/json"
)

type ServiceResult struct {
    Type    string      `json:"type"`
    Content interface{} `json:"content"`
}

type Person struct {
    Name string `json:"name"`
}

func main() {

    nikola := ServiceResult{}
    nikola.Type = "Person"
    nikola.Content = Person{"Nikola"}

    js, _ := json.Marshal(nikola)
    fmt.Println("Marshalled object: " + string(js))
}
  

现在我想从这个JSON字符串创建一个新人,但是   必须从JSON字符串中读取类型。

{"type":"Person","content":{"name":"Nikola"}}

2 个答案:

答案 0 :(得分:3)

首先,为您的类型

type ServiceResult struct {
    Type    string      `json:"type"`
    Content interface{} `json:"content"`
}

您需要通过定义来实现“自定义JSON解组器” 方法:

func (sr *ServiceResult) UnmarshalJSON(b []byte) error

使您的类型满足encoding/json.Unmarshaler接口 - 这将使JSON解码器在解组时调用该方法 该类型的价值。

在该方法中,您可以使用辅助类型

type typedObject struct {
    Type    string          `json:"type"`
    Content json.RawMessage `json:"content"`
}

首先解冻b切片。

如果完成解编而不会产生错误,那么你的价值就是如此 类型typedObject的类型将包含描述该类型的字符串 在其Type字符串和包含的原始(未解析)JSON字符串中 在其Content字段的“内容”字段中。

然后执行switch(或地图查找或其他)来执行 选择实际的Go类型来解组Content中的任何数据 字段,如:

var value interface{}
switch sr.Type {
case "person":
    value = new(Person)
case "car":
    value = new(Car)
}
err = json.Unmarshal(sr.Content, value)

...其中PersonCar是具体的结构类型 适合encoding/json消费。

请阅读thisthis 要充分了解这些概念。

答案 1 :(得分:-1)

当你从ServiceResult创建实例时,你可以用person初始化内容然后解组它:

service := ServiceResult{Content: Person{}}
json.Unmarshal(data, &service)