web-dev-qa-db-fra.com

Comment démarshal JSON dans l'interface {} dans Go?

Je suis un débutant à Go et maintenant j'ai un problème. J'ai un type appelé Message, c'est une structure comme celle-ci:

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

J'ai également un type appelé CreateMessage comme celui-ci:

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

Et j'ai une chaîne JSON comme {"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}}.

Lorsque j'utilise json.Unmarshal pour décoder cela en une variable Message, la réponse est {Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}.

Alors pourrais-je décoder le JSON en une structure de Message et changer son interface de données {} pour taper CreateMessage selon le Cmd?

J'ai essayé de convertir les données directement en type CreateMessage mais le complice m'a dit que les données sont un type de carte {sting] interface {}.

25
Shanicky_C

Définissez un type de structure pour la partie fixe du message avec un champ json.RawMessage pour capturer la partie variante du message. Définissez des types de struct pour chacun des types de variantes et décodez-les en fonction de la commande.

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

exemple de terrain de je

34
Cerise Limón