Подтвердить что ты не робот

Как развязать json в интерфейс {} в golang?

Я новичок в golang, и теперь у меня есть проблема. У меня есть тип, называемый Message, это такая структура:

type Message struct {
    Cmd string `json:"cmd"`
    Data interface{} `json:"data"`
}

У меня также есть тип CreateMessage, например:

type CreateMessage struct {
    Conf map[string]int `json:"conf"`
    Info map[string]int `json:"info"`
}

И у меня есть строка json как {"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}}.

Когда я использую json.Unmarshal, чтобы декодировать это в переменную Message, ответ будет {Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}.

Итак, можно ли декодировать json в структуру Message и изменить его интерфейс данных {}, чтобы ввести CreateMessage в соответствии с Cmd?

Я попытался преобразовать данные непосредственно в тип CreateMessage, но компилятор сказал мне, что Data является типом интерфейса map [sting] {}.

4b9b3361

Ответ 1

Определите тип структуры для фиксированной части сообщения с полем json.RawMessage, чтобы зафиксировать вариантную часть сообщения. Определите типы структур для каждого из типов вариантов и декодируйте их на основе команды.

type Message struct {
  Cmd string `json:"cmd"`
  Data      json.RawMessage
}  

type CreateMessage struct {
    Conf map[string]int `json:"conf"`
    Info map[string]int `json:"info"`
}  

func main() {
    var m Message
    if err := json.Unmarshal(data, &m); err != nil {
        log.Fatal(err)
    }
    switch m.Cmd {
    case "create":
        var cm CreateMessage
        if err := json.Unmarshal([]byte(m.Data), &cm); err != nil {
            log.Fatal(err)
        }
        fmt.Println(m.Cmd, cm.Conf, cm.Info)
    default:
        log.Fatal("bad command")
    }
}

пример игровой площадки