2016-01-18 55 views
1

此作品:http://play.golang.org/p/-Kv3xAguDRUnmarshalJSON堆棧溢出結果

這會導致堆棧溢出:http://play.golang.org/p/1-AsHFj51O

我不明白爲什麼。在這種情況下使用JSONUnmarshaler接口的正確方法是什麼?

package main 

import (
    //"bytes" 
    "encoding/json" 
    "fmt" 
    "strings" 
) 

type T interface { 
    Printer() 
} 

type A struct{ JA string } 

func (t A) Printer() { fmt.Print("A") } 

/* 
func (t *A) UnmarshalJSON(data []byte) error { 
    i := A{} 
    dec := json.NewDecoder(bytes.NewReader(data)) 
    if err := dec.Decode(&i); err != nil { 
     return err 
    } 
    i.Printer() 
    *t = i 
    return nil 
} 
*/ 

var vI []T 

func main() { 
    vI = []T{&A{}} 
    get() 
} 

func get() { 
    dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OK\"}]")) 
    if err := dec.Decode(&vI); err != nil { 
     fmt.Print(err) 
    } 
    for _, v := range vI { 
     v.Printer() 
    } 
} 

回答

1

dec.Decode(&i) 

會打電話給你UnmarshalJSON,這反過來將調用Decode,等等。如果您需要解組的JSON,然後用它做什麼,一個整潔的技術是聲明局部類型,解組數據進去,然後再轉換回所需的類型:

// Type a has no UnmarshalJSON. 
type a A 
i := a{} 
dec := json.NewDecoder(bytes.NewReader(data)) 
if err := dec.Decode(&i); err != nil { 
    return err 
} 
// Convert back to A. 
tt := A(i) 
tt.Printer() 
*t = tt 
// ... 

遊樂場:http://play.golang.org/p/HWamV3MbvW

a類型沒有方法(所以沒有堆棧溢出),但是convertibleA