2015-01-31 4 views
14

저는 골란의 초보자입니다. 이제 문제가 생깁니다. 내가 메시지라는 형식을 가지고,이 같은 구조체는 다음과 같습니다json을 golang의 {} 인터페이스로 비 정렬 화하는 방법은 무엇입니까?

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

을 내가 {"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}} 같은 JSON 문자열이 있습니다.

json.Unmarshal을 사용하여이를 메시지 변수로 디코딩 할 때 응답은 {Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}입니다.

그래서 json을 Message 구조체로 디코딩하고 데이터 인터페이스 {}를 변경하여 Cmd에 따라 CreateMessage를 입력 할 수 있습니까?

데이터를 직접 CreateMessage 유형으로 변환하려고했지만 컴파일러가 Data가 map [스팅] 인터페이스 {} 유형이라고 알려주었습니다.

답변

21

json.RawMessage 필드를 사용하여 메시지의 고정 부분에 대한 구조 유형을 정의하여 메시지의 변형 부분을 캡처하십시오. 각 변형 유형에 대해 struct 유형을 정의하고 명령에 따라 변형합니다.

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

관련 문제