2015-01-31 13 views
14

Golang'da yeni biriyim ve şimdi bir sorunum var. Ben İleti denilen bir türü var, böyle bir yapıdır:Jlang'ı arabirimde {} inlanguma nasıl dönüştürebilirsiniz?

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

Ben de böyle CreateMessage adlı bir türü var:

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

Ve {"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}} gibi bir json dize var.

json.Unmarshal'u İleti değişkenine dönüştürmek için kullandığımda, yanıt {Cmd:create Data:map[conf:map[a:1] info:map[b:2]]} olur.

Bu nedenle json'u bir Message yapısına çözebilir ve Cmd'ye göre CreateMessage yazarak Data'nın arabirimini {} değiştirebilir miyim?

Verileri doğrudan CreateMessage biçimine dönüştürmeyi denedim, ancak derleyici Data'nın bir [sting] interface {} türü olduğunu söyledi.

cevap

21

İletinin varyant bölümünü yakalamak için iletinin sabit kısmı için bir json.RawMessage alanıyla bir yapı türü tanımlayın. Varyant türlerinin her biri için yapı tiplerini tanımlayın ve bu komutlara göre bunları çözün.

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

playground example

İlgili konular