dongxing2030 2018-06-01 11:08
浏览 154
已采纳

在Golang中处理JSON继承

I have a Java code that handles json inheritance the code is like this :

public class BaseMessage {
    private String messageId;
    private Integer type;
    ...
}

public class TextMessage  extends BaseMessage {
    private String recipient;
    private String sender;
    ...
}

public class SystemTextMessage  extends BaseMessage {
    private String field1;
    private String field2;
    ...
}

And some other classes

And I'm using Gson library like this:

    RuntimeTypeAdapterFactory<BaseMessage> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
            .of(BaseMessage.class, "type")
            .registerSubtype(TextMessage.class,
                    String.valueOf(MessageType.TEXT_MESSAGE))
            .registerSubtype(SystemTextMessage.class,
                    String.valueOf(MessageType.SYSTEM_MESSAGE))
            ;

Gson gson = new GsonBuilder().registerTypeAdapterFactory(runtimeTypeAdapterFactory).create();
Type listType = new TypeToken<List<BaseMessage>>(){}.getType();
List<BaseMessage> list = gson.fromJson(json, listType);

And then I just iterate through the List and comparing by "instanceof".

And what about golang? Is there any way to do same thing? I failed to find something similar. Any 1 can help? Thank you.

  • 写回答

2条回答 默认 最新

  • duanbishai5271 2018-06-01 12:08
    关注

    Without using any external library, you could do:

    package main
    
    import (
        "encoding/json"
        "fmt"
        "reflect"
    )
    
    type BaseMessage struct {
        MessageId string `json:"messageId"`
        Type      int    `json:"type"`
    }
    
    type TextMessage struct {
        *BaseMessage
        Field1 string `json:"field1"`
        Field2 string `json:"field2"`
    }
    
    type SystemTextMessage struct {
        *BaseMessage
        Field1 string `json:"field1"`
        Field2 string `json:"field2"`
    }
    
    func parseJson(input []byte) []interface{} {
        var raw []map[string]interface{}
    
        json.Unmarshal(input, &raw)
        var elements []interface{}
        for _, element := range raw {
            typeId := int(element["type"].(float64))
    
            base := &BaseMessage{
                MessageId: element["messageId"].(string),
                Type:      typeId,
            }
            switch typeId {
            case 1:
                elements = append(elements, &TextMessage{base, element["field1"].(string), element["field2"].(string)})
                break
            case 2:
                elements = append(elements, &SystemTextMessage{base, element["field1"].(string), element["field2"].(string)})
                break
            }
        }
    
        return elements
    }
    
    func main() {
        input := []byte(`
                 [{
                   "messageId": "text",
                   "type": 1,
                   "field1": "field 1",
                   "field2": "field 2"
                 }, {
                   "messageId": "system",
                   "type": 2,
                   "field1": "field 1",
                   "field2": "field 2"
                 }]
            `)
    
        for _, element := range parseJson(input) {
            fmt.Println(reflect.TypeOf(element))
        }
    }
    

    You can give it a try here: https://play.golang.org/p/hB8qG6oflhR

    Be careful though, the code is not handling errors.

    I'm not sure if there's a more automatic way of doing it, but I believe you have to work with bare interface{} here.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 qgcomp混合物线性模型分析的代码出现错误:Model aliasing occurred
  • ¥100 已有python代码,要求做成可执行程序,程序设计内容不多
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助
  • ¥15 STM32控制MAX7219问题求解答
  • ¥20 在本地部署CHATRWKV时遇到了AttributeError: 'str' object has no attribute 'requires_grad'