Как развязать 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] {}.
Ответы
Ответ 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")
}
}
пример игровой площадки