2014-04-23 1 views
8

나는이 structjson.RawMessage를 구조체로 변환하는 적절한 방법은 무엇입니까?

type SyncInfo struct { 
    Target string 
} 

가 지금은 ElasticSearch 일부 json 데이터를 쿼리 할 수 ​​있습니다. Sourcejson.RawMessage입니다. 내가 원하는 것은 source을 내 SyncInfo에 매핑하여 mySyncInfo 변수를 생성 한 것입니다.

나는 그것을하는 방법을 알아 냈다. .. 그러나 그것은 별나다. 먼저 MarshalJSON()을 호출하여 []byte을 얻은 다음 json.Unmarshal()에 피드를 입력하고 []byte과 내 구조체에 대한 포인터를 가져옵니다.

괜찮 으면 작동하지만 마치 여분의 홉을하고있는 것처럼 느껴집니다. 나는 뭔가를 놓치고 있거나 json.RawMessage에서 struct으로 갈 방법이 있나?

var mySyncInfo SyncInfo 

jsonStr, _ := out.Hits.Hits[0].Source.MarshalJSON() 
json.Unmarshal(jsonStr, &mySyncInfo) 

fmt.Print(mySyncInfo.Target) 

답변

13

으로는 json.Unmarshal에 데이터를 매개 변수로 json.RawMessage을 사용할 수 있도록 json.RawMessage의 기본 유형, []byte입니다 말했다.

그러나 문제는 포인터가 (*json.RawMessage) 값이 아니라는 것입니다. 당신이 할 일은 그것을 역 참조하는 것입니다

err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo) 

근무 예 :

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type SyncInfo struct { 
    Target string 
} 

func main() { 
    data := []byte(`{"target": "localhost"}`) 
    Source := (*json.RawMessage)(&data) 

    var mySyncInfo SyncInfo 
    // Notice the dereferencing asterisk * 
    err := json.Unmarshal(*Source, &mySyncInfo) 
    if err != nil { 
     panic(err) 
    } 

    fmt.Printf("%+v\n", mySyncInfo) 
} 

출력 :

{Target:localhost} 

놀이터 :http://play.golang.org/p/J8R3Qrjrzx

+2

타다! 너는 남자 야! Go :-)와의 첫날. – Christoph

+0

환영합니다 :) 그리고 행복하게 코딩하십시오! – ANisus

2

json.RawMessage은 실제로는 단지 바이트 조각입니다. 오류를 반환 할 수 있습니다

json.Unmarshal(out.Hits.Hits[0].Source, &mySyncInfo) 
다소 관련이없는 또

,하지만 json.Unmarshal 당신은 그것을 처리하는 경우 : 당신은 너무 같이 직접 json.Unmarshal에 직접 공급 할 수 있어야한다.

err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo) 
if err != nil { 
    // Handle 
} 
+0

이렇게하면 형식 오류가 발생합니다. 'hit.Source (type * json.RawMessage)를 함수 인수의 형식 [] 바이트로 사용할 수 없습니다. ' – Christoph

+0

아, 바로 값을 참조해야합니다. json.RawMessage 대신 * json.RawMessage를 전달하십시오. 이 변경 사항을 반영하기 위해 답변에서 예제를 업데이트했습니다. –

관련 문제