【问题标题】:Unmarshalling JSON into Go interface{}将 JSON 解组为 Go 接口{}
【发布时间】:2014-07-24 21:30:57
【问题描述】:

我有一个带有interface{} 类型字段的结构。在使用 memcached (https://github.com/bradfitz/gomemcache) 对其进行缓存的过程中,该结构被编组为 JSON,然后在从缓存中检索时将其解组回该结构。生成的interface{} 字段不可避免地指向类型为 map[string]interface{} 的对象(如interface{} 字段只能类型断言为 map[string]interface{}),编组和解组过程没有保留类型信息。有没有办法在编组过程中保存这些信息,以便可以正确解组?还是我必须使用其他编解码器或其他东西?

type A struct {
    value interface{}
}

type B struct {
    name string
    id string
}

func main() {
    a := A{value: B{name: "hi", id: "12345"}}
    cache.Set("a", a) // Marshals 'a' into JSON and stores in cache
    result = cache.Get("a") // Retrieves 'a' from cache and unmarshals
    fmt.Printf("%s", result.value.(B).name) // Generates error saying that 
        // map[string]interface{} cannot be type asserted as a 'B' struct
    fmt.Printf("%s", result.value.(map[string]interface{})["name"].(string)) // Correctly prints "12345"
}

【问题讨论】:

  • 标题应该是:Unmarshalling JSON into Go interface{}?
  • 是的,我就是这个意思

标签: json go memcached


【解决方案1】:

短版,不,你不能这样做,但你几乎没有选择。

  1. A.Value 更改为使用B 而不是interface{}
  2. A 添加一个函数,将A.Value 从映射转换为B(如果它还不是B)。
  3. 使用encoding/gob 并将字节存储在内存缓存中,然后使用NewA(b []byte) *A 之类的函数将其转换回来。

对于使用gob,您必须在编码/解码之前先注册每个结构,example

func init() {
    //where you should register your types, just once
    gob.Register(A{})
    gob.Register(B{})
}
func main() {
    var (
        buf bytes.Buffer
        enc = gob.NewEncoder(&buf)
        dec = gob.NewDecoder(&buf)
        val = A{B{"name", "id"}}
        r   A
    )
    fmt.Println(enc.Encode(&val))
    fmt.Println(dec.Decode(&r))
    fmt.Printf("%#v", r)
}

【讨论】:

  • 嗯,我想我会试试 gob。这个函数写起来会很痛苦,而且只会占用空间,更不用说错误检查了。
  • 嗯,我什至不确定 encoding/gob 是否允许您存储接口的底层类型...可能无论如何都必须编写函数
  • 可以,但是您必须使用gob.Register注册每种类型。
  • 太棒了,错过了在查看文档时,我直接跳到了编码器
【解决方案2】:

JSON 无法像 Go 中那样编码深度的类型信息,因此在解组时总是会返回以下基本类型:

bool,用于 JSON 布尔值

float64,用于 JSON 数字

字符串,用于 JSON 字符串

[]接口{},用于 JSON 数组

map[string]interface{},用于 JSON 对象

JSON 为空

来自 Go 文档:http://golang.org/pkg/encoding/json/#Unmarshal

如果了解你需要的类型,也许你可以编写一些方法来构造正确的解组变量?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    相关资源
    最近更新 更多