小编典典

UnmarshalJSON导致堆栈溢出

go

这有效:http :
//play.golang.org/p/-Kv3xAguDR。

这导致堆栈溢出: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()
    }
}

阅读 286

收藏
2020-07-02

共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没有方法(因此没有堆栈溢出),但是可以转换A

2020-07-02