简体   繁体   English

如何在Go中将JSON解组到接口

[英]How to Unmarshal JSON into an interface in Go

I am trying to simultaneously unmarshal and strip fields from a number of different JSON responses into appropriate Go structs. 我试图同时解组和剥离来自许多不同的JSON响应的字段到适当的Go结构。 To do this, I created a Wrappable interface that defines the Unwrap method (which strips the appropriate fields) and pass that interface to the code that unmarshals and unwraps. 为此,我创建了一个Wrappable接口,该接口定义Unwrap方法(剥离相应的字段),并将该接口传递给解组和解包的代码。 It looks like the following example (also at http://play.golang.org/p/fUGveHwiz9 ): 看起来像以下示例(也位于http://play.golang.org/p/fUGveHwiz9 ):

package main

import (
    "encoding/json"
    "fmt"
)

type Data struct {
    A string `json:"a"`
    B string `json:"b"`
}

type DataWrapper struct {
    Elements []Data `json:"elems"`
}

type Wrapper interface {
    Unwrap() []interface{}
}

func (dw DataWrapper) Unwrap() []interface{} {
    result := make([]interface{}, len(dw.Elements))
    for i := range dw.Elements {
        result[i] = dw.Elements[i]
    }
    return result
}

func unmarshalAndUnwrap(data []byte, wrapper Wrapper) []interface{} {
    err := json.Unmarshal(data, &wrapper)
    if err != nil {
        panic(err)
    }
    return wrapper.Unwrap()
}

func main() {
    data := `{"elems": [{"a": "data", "b": "data"}, {"a": "data", "b": "data"}]}`
    res := unmarshalAndUnwrap([]byte(data), DataWrapper{})
    fmt.Println(res)
}

However, when I run the code, Go panics with the following error: 但是,当我运行代码时,出现以下错误导致出现紧急情况:

panic: json: cannot unmarshal object into Go value of type main.Wrapper

It seems the unmarshaller doesn't want to be passed a pointer to an interface. 似乎解组器不想传递给接口的指针。 I am somewhat surprised by this given that I can get at the underlying type and fields using the reflect package within the unmarshalAndUnwrap method. 鉴于我可以使用unmarshalAndUnwrap方法中的reflect包了解底层类型和字段,因此对此我感到有些惊讶。 Can anyone provide insight into this problem and how I might work around it? 谁能提供对此问题的见解以及我如何解决该问题?

As you stated, passing a non-pointer fails. 如您所述,传递非指针失败。 Why are you trying to do this anyway? 您为何仍要尝试这样做?

Replace 更换

res := unmarshalAndUnwrap([]byte(data), DataWrapper{})

by 通过

res := unmarshalAndUnwrap([]byte(data), &DataWrapper{})

It should do the trick and it avoid unnecessary copy. 它可以解决问题,避免不必要的复制。

This error should help you understand: http://play.golang.org/p/jXxCxPQDOw 此错误应该可以帮助您了解: http : //play.golang.org/p/jXxCxPQDOw

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM