UnmarshalJSON导致堆栈溢出 [英] UnmarshalJSON results in stack overflow

查看:169
本文介绍了UnmarshalJSON导致堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此作品: http://play.golang.org/p/-Kv3xAguDR

这会导致堆栈溢出: http://play.golang.org/p/1-AsHFj51O



我不明白为什么。在这种情况下,使用 JSONUnmarshaler 接口的正确方法是什么?

  


//bytes
encoding / json
fmt
strings


type T interface {
Printer()
}

type A struct {JA string}

func(t A )打印机(){fmt.Print(A)}
$ b / *
func(t * A)UnmarshalJSON(data [] byte)错误{
i:= A {}
dec:= json.NewDecoder(bytes.NewReader(data))
if err:= dec.Decode(& i); err!= nil {
return err
}
i.Printer()
* t = i
return nil
}
* /
$ b 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()
}


解决方案


  dec.Decode(& i)

会调用你的 UnmarshalJSON ,这又会调用 Decode ,依此类推。如果你需要解组你的JSON,然后对它做些什么,一个简单的技巧是声明一个本地类型,解组你的数据,然后转换回你想要的类型:

  //输入a没有UnmarshalJSON。 
键入a
i:= a {}
dec:= json.NewDecoder(bytes.NewReader(data))
if err:= dec.Decode(& i) ; err!= nil {
return err
}
//转换回A.
tt:= A(i)
tt.Printer()
* t = tt
// ...

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



类型 a 没有方法(所以没有堆栈溢出),但是 convertible to A


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

This results in a stack overflow: http://play.golang.org/p/1-AsHFj51O.

I fail to understand why. What is the correct way 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()
    }
}

解决方案

This

dec.Decode(&i)

will call your UnmarshalJSON, which in turn will call Decode, and so on. If you need to unmarshal your JSON and then do something with it, one neat technique is to declare a local type, unmarshal your data into it, and then convert back to your desired type:

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

The type a has no methods (so no stack overflow), but is convertible to A.

这篇关于UnmarshalJSON导致堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆