2017-09-27 71 views
1

我是Golang的新手。我正在尋找一種方式來做一些自定義的東西,用於封送和解組json。我找到了實施MarshallerUnmarshaller接口的解決方案。Go json Unmarshaller不叫

這是我struct與實現的接口(我還實施斯金格):

type Data struct { 
    Foo string `json:"foo"` 
    bar string 
} 

func (d Data) MarshalJSON() ([]byte, error) { 
    return []byte("{\"foo\":\"test\",\"bar\":\"data\"}"), nil 
} 

func (d Data) String() string { 
    return fmt.Sprintf("Foo: %s, bar: %s", d.Foo, d.bar) 
} 

func (d Data) UnmarshalJSON(b []byte) error { 
    d.bar = "testtest" 
    d.Foo = "data" 
    return nil 
} 

對於Marshaller一切正常:

data := &Data{} 
marshal, _ := json.Marshal(data) 
fmt.Println(string(marshal)) 

預期輸出:

{「foo」:「test」,「bar」:「data」}

,我期待但Unmarshaller的不工作:

jsonData := "{\"foo\":\"test\"}" 
data := Data{} 
json.Unmarshal([]byte(jsonData), data) 
fmt.Println(data) 

此代碼打印:

富:,酒吧:

有沒有辦法,我的東西在這裏失蹤?

回答

7

這裏有幾個不同的問題。

  • 如果您想要修改接收器,則方法接收器必須是指針,否則您只修改局部方法的副本。你總是需要解組成一個指針。

  • 你聲明的Foo領域"field" JSON標籤,但傳遞"foo"

  • 你打電話json.UnmarshalUnmarshalJSON方法,它是將無限期遞歸內。

工作示例看起來像

func (d *Data) UnmarshalJSON(b []byte) error { 
    type data Data 
    tmp := &data{bar: "bar"} 
    err := json.Unmarshal(b, tmp) 
    if err != nil { 
     return err 
    } 
    *d = Data(*tmp) 
    return nil 
} 

func main() { 
    jsonData := "{\"field\":\"test\"}" 
    data := Data{} 
    json.Unmarshal([]byte(jsonData), &data) 
    fmt.Printf("%#v\n", data) 
} 

https://play.golang.org/p/FnF2li63dt

+0

對不起,該點數3,4是我的錯。我在編輯器中進行了更改,但沒有將其複製到此處。 –

+0

隨着指針的工作,謝謝。但是我發現有點奇怪,你必須在一個指針上實現一個方法來完成這個工作。這對我來說不是很明顯,也許只是因爲我是Golang的新手 –