Обработка наследования JSON в Голанге - PullRequest
0 голосов
/ 01 июня 2018

У меня есть Java-код, который обрабатывает наследование json, код выглядит так:

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;
    ...
}

И некоторые другие классы

И я использую библиотеку Gson, например:

    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);

А потом я просто перебираю список и сравниваю по "instanceof".

А как насчет Голанга?Есть ли способ сделать то же самое?Мне не удалось найти что-то подобное.Любой 1 может помочь?Спасибо.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Без использования какой-либо внешней библиотеки вы можете сделать:

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))
    }
}

Вы можете попробовать здесь: https://play.golang.org/p/hB8qG6oflhR

Будьте внимательны, код не обрабатывает ошибки.

Я не уверен, есть ли более автоматический способ сделать это, но я считаю, что вам нужно работать с голым interface{} здесь.

0 голосов
/ 01 июня 2018

В Go вы пишете вместо наследования.Ниже структура Tesla встраивает как Car, так и Computer, определяя их как анонимные поля (т.е. не давая им имя.)

package main

import (
    "fmt"
    "encoding/json"
)

type Car struct {
    Speed int
}

type Computer struct {
    Cores int
    Memory int
}

type Tesla struct {
    Car
    Computer
}

func main() {
    tesla := Tesla{
        Car{Speed: 200},
        Computer{Cores: 4, Memory: 4192},
    }
    b, _ := json.MarshalIndent(tesla, "", "\t")
    fmt.Println(string(b))
}

Выходы:

{
    "Speed": 200,
    "Cores": 4,
    "Memory": 4192
}

Попробуйте на игровой площадке Go .В этом примере кодируется JSON, используйте json.Unmarshal для декодирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...