忽略JSON Marshal上不受支持的类型错误

时间:2018-03-17 08:48:48

标签: json go

这是我的代码:

func dump(w io.Writer, val interface{}) error {
    je := json.NewEncoder(w)
    return je.Encode(val)   
}

type example struct {
    Name string
    Func func() 
}

func main() {
    a := example{
        Name: "Gopher",
        Func: func() {},
    }
    err := dump(os.Stdout, a)
    if err != nil {
        panic(err)
    }
}

程序会因json: unsupported type: func()

而感到恐慌

我的问题是,如何将ANYTHING编码为json,忽略编码无法处理的那些。例如,上面的数据结构,我希望输出为:{"Name": "Gopher"}

重要提示:对于转储功能,其值为interface{},即不知道它将接收哪种数据,因此json:"-"等技巧我想要的是什么。

如果传递给dump()的数据不是marshal-able,例如dump(func(){}),只返回空字符串是完全可以接受的。

3 个答案:

答案 0 :(得分:2)

JSON标签(正确方式)

这是你在找什么:playground

您可以使用字段标记来提供有关如何处理结构的json说明。有关您拥有的选项的详细信息,另请参阅encoding/json

- 编辑 -

val属于interface{}类型并不重要。 json.Marshal()无论如何都会反思它,并找出它是什么类型。程序员的工作是在他/她想要json的所有结构上设置正确的dump标签。

自定义元帅功能(这里不是必要的另一种方式)

您还可以编写自定义MarshalJSON函数来对所有类型进行编组操作:custom marshalling playground

你自己的json Marshaller(按你的方式行事)

如果你不喜欢golang处理json编组的方式,你总是可以编写自己的编组功能来自己做所有的反射。

答案 1 :(得分:0)

您可以使用json.RawMessage。它可用于延迟JSON解码或预先计算JSON编码。

答案 2 :(得分:0)

如果你只想记录整个结构,你可以这样做。

func dump(w io.Writer, val interface{}) error {
    je := json.NewEncoder(w)
    return je.Encode(val)
}

type example struct {
    Name string
    Func func()
}

func main() {
    a := example{
        Name: "Gopher",
        Func: func() {},
    }
    type _example struct {
        example
        Func interface{}
    }
    err := dump(os.Stdout, _example{example: a})
    if err != nil {
        panic(err)
    }
}

这是一个记录整个 http.Request 的例子。

type _Request struct {
    *http.Request
    GetBody interface{}
    Cancel  interface{}
}
j, err := json.MarshalIndent(_Request{Request: r}, "", "    ")