【问题标题】:How to unmarshal from interface{} to interface{} in Go如何在 Go 中从 interface{} 解组到 interface{}
【发布时间】:2017-04-10 22:25:00
【问题描述】:

我的系统中有多个节点通过 RPC 进行通信。我正在尝试通过 RPC 将 map[string] interface{} 发送到另一个节点。发送方使用 json.Marshal 接收方使用 json.Unmarshal 获取地图。 假设在发送方,map 包含 [1] => 2,其中 2 是 uint32 类型。
问题是 Unmarshal 尝试查找基础数据的类型,并根据此处 https://blog.golang.org/json-and-go 指定的默认行为将 2 转换为 float64 类型。后来,将 float64 转换为 uint32 会引起恐慌。

我提到了How to unmarshal json into interface{} in golang?。但是为此,我们需要知道数据的类型。在我的情况下,数据可以是任何类型,所以我想将其保留为 interface{}。如何从 interface{} 解组到 interface{}?

【问题讨论】:

    标签: json go unmarshalling


    【解决方案1】:

    很遗憾,您不能使用 encoding/json 包,因为类型信息不会传输,并且如果类型信息不存在,默认情况下 JSON 数字会解组为 float64 类型的值。您需要定义 struct 类型,其中明确声明该字段的类型为 uint32

    或者,您可以选择使用encoding/gob,它确实传输和保留类型信息。看这个例子:

    m := map[string]interface{}{"1": uint32(1)}
    
    b := &bytes.Buffer{}
    gob.NewEncoder(b).Encode(m)
    
    var m2 map[string]interface{}
    gob.NewDecoder(b).Decode(&m2)
    fmt.Printf("%T\n%#v\n", m2["1"], m2)
    

    输出(在Go Playground上试试):

    uint32
    map[string]interface {}{"1":0x1}
    

    gob 的缺点是它是特定于 Go 的,不像独立于语言和平台的 JSON。

    【讨论】:

      猜你喜欢
      • 2015-03-31
      • 2018-12-12
      • 2016-09-18
      • 2014-03-10
      • 2016-05-21
      • 2020-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多