UnmarshalJSON causes stack overflow

This works: http://play.golang.org/p/-Kv3xAguDR .

This leads to a stack overflow: http://play.golang.org/p/1-AsHFj51O .

I do not understand why. How to use the JSONUnmarshaler interface in this case?

 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
source share
1 answer

it

 dec.Decode(&i) 

will call your UnmarshalJSON , which in turn will call Decode , etc. If you need to unmount JSON and then do something with it, one neat technique is to declare a local type, untie your data, and convert it back to the type you need:

 // 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 // ... 

Playground: http://play.golang.org/p/HWamV3MbvW .

Type a has no methods (therefore not), but convertible to a .

+1
source

Source: https://habr.com/ru/post/1258770/


All Articles