【问题标题】:How to Unmarshal JSON into an interface in Go如何将 JSON 解组到 Go 中的接口中
【发布时间】:2013-07-23 05:02:47
【问题描述】:

我正在尝试同时将多个不同 JSON 响应中的字段解组和剥离到适当的 Go 结构中。为此,我创建了一个 Wrappable 接口,该接口定义了 Unwrap 方法(去除相应的字段)并将该接口传递给解组和解包的代码。它看起来像下面的例子(也在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)
}

但是,当我运行代码时,Go 出现以下错误:

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

似乎解组器不想被传递一个指向接口的指针。考虑到我可以使用 unmarshalAndUnwrap 方法中的反射包来获取底层类型和字段,我对此感到有些惊讶。谁能提供有关此问题的见解以及我如何解决它?

【问题讨论】:

    标签: json go


    【解决方案1】:

    正如您所说,传递非指针失败。你为什么要这样做?

    替换

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

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

    它应该可以解决问题并且避免不必要的复制。

    这个错误应该可以帮助你理解:http://play.golang.org/p/jXxCxPQDOw

    【讨论】:

    • 最终,这就是我最终要做的。由于示例代码中没有出现的其他原因,not 传递指针更有意义,但将其更改为指针 did 工作。 JSON unmarshaller 不能对接口值进行操作仍然困扰着我,因为底层的具体类型可通过反射包(由 json 包使用)获得。
    • 这对我也有帮助。我认为这是因为,如果您在接口内存储非指针对象(如 DataWrapper{}),“反射”或类型断言只能获取原始非指针对象的重复对象,因此不能t 将值分配给您的原始值。但是,如果您在其中保存一个指针(如 &DataWrapper{}),golang 将能够找到正确的内存地址并最终更新这些值。
    猜你喜欢
    • 1970-01-01
    • 2018-11-15
    • 2015-03-31
    • 2019-01-13
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2016-12-16
    • 2015-07-21
    相关资源
    最近更新 更多