在Go中如何从接口{}解组到接口{} [英] How to unmarshal from interface{} to interface{} in Go

查看:100
本文介绍了在Go中如何从接口{}解组到接口{}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的系统中有多个节点通过RPC进行通信。我想通过RPC发送一个map [string] interface {}到另一个节点。发件人使用json.Marshal和接收器使用json.Unmarshal来获取地图。
让我们在发送方说,映射包含[1] => 2其中2是uint32类型。

问题是Unmarshal尝试查找基础数据的类型并将2转换为float64类型根据此处指定的默认行为 https://blog.golang.org/json-和去。之后,将float64转换为uint32会导致恐慌。

我指的是如何将json解组到在golang中的接口{}中?。但为此,我们需要知道数据的类型。在我的情况下,数据可以是任何类型,所以我想保留它作为interface {}。如何从界面{}解组到接口{}?

解决方案

不幸的是,使用 encoding / json 你不能这样做,因为类型信息没有被传输,默认情况下JSON数字被解组为<$如果类型信息不存在,c $ c> float64 键入。您需要定义 struct 类型,其中您明确指出该字段类型为 uint32



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

$ pre $ m $ c $ m $ = map [string] interface {} {1:uint32(1)}

b:=&; bytes.Buffer {}
gob.NewEncoder(b).Encode(m)

var m2 map [string] interface {} $ b $ (b)。解码(& m2)
fmt.Printf(%T \%%#v\\\
,m2 [1],m2)

输出(在 Go Playground ):

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

gob 就是Go-specific,与语言和平台无关的JSON不同。


There are multiple nodes in my system which communicate through RPC. I am trying to send a map[string] interface{} to another node through RPC. Sender uses json.Marshal and receiver uses json.Unmarshal to get the map. Let us say at the sender side, map contains [1] => 2 where 2 is of type uint32.
The problem is Unmarshal tries to find the type of underlying data and converts 2 to float64 type according to its default behavior as specified here https://blog.golang.org/json-and-go. Later, casting float64 to uint32 causes panic.

I refered to How to unmarshal json into interface{} in golang? . But for this, we need to know the type of data. In my case data can be of any type so I want to keep it as interface{}. How do I unmarshal from interface{} to interface{}?

解决方案

Unfortunately using the encoding/json package you can't, because type information is not transmitted, and JSON numbers by default are unmarshaled into values of float64 type if type information is not present. You would need to define struct types where you explicitly state the field is of type uint32.

Alternatively you may opt to use encoding/gob which does transmit and preserve type information. See this example:

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)

Output (try it on the Go Playground):

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

The downside of gob is that it's Go-specific unlike the language and platform independent JSON.

这篇关于在Go中如何从接口{}解组到接口{}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆