我string通过Rabbitmq消息系统获得了。在发送之前,
string
我使用json.Marshal,将结果转换为string并通过Rabbitmq发送。
json.Marshal
我转换和发送的结构可以是:(更改了结构的名称和大小,但这没有关系)
type Somthing1 struct{ Thing string `json:"thing"` OtherThing int64 `json:"other_thing"` }
要么
type Somthing2 struct{ Croc int `json:"croc"` Odile bool `json:"odile"` }
消息完全像a一样经过,string并打印在另一面(某些服务器)
到目前为止,一切正常。现在,我试图将它们转换回它们的结构并声明类型。
第一次尝试是通过:
func typeAssert(msg string) { var input interface{} json.Unmarshal([]byte(msg), &input) switch input.(type){ case Somthing1: job := Somthing1{} job = input.(Somthing1) queueResults(job) case Somthing2: stats := Somthing2{} stats = input.(Somthing2) queueStatsRes(stats) default: }
这是行不通的。当input在拆封后打印它的类型时,我得到map[string]interface{}(?!?)
input
map[string]interface{}
甚至比这更奇怪,映射键是我得到的字符串,映射值是空的。
我做了其他一些尝试,例如:
func typeAssert(msg string) { var input interface{} json.Unmarshal([]byte(msg), &input) switch v := input.(type){ case Somthing1: v = input.(Somthing1) queueResults(v) case Somthing2: v = input.(Somthing2) queueStatsRes(v) default: }
并且还尝试编写此答案中解释的开关: Golang:无法在非接口值上键入switch
switch v := interface{}(input).(type)
仍然没有成功…
有任何想法吗?
功能文档json中显示了包解组到的默认类型Unmarshal
json
Unmarshal
bool, for JSON booleans float64, for JSON numbers string, for JSON strings []interface{}, for JSON arrays map[string]interface{}, for JSON objects nil for JSON null
由于您要编组为interface{},因此返回的类型将仅来自该集合。该json软件包不了解Something1和Something2。您需要从将map[string]interface{}json对象解组为的转换,或者直接解组为所需的struct类型。
interface{}
Something1
Something2
如果您不想从通用接口中解压缩数据,或者以某种方式标记数据以便知道期望的类型,则可以迭代地获取json并尝试将其解编为所需的每种类型。
您甚至可以将它们打包到包装结构中,为您进行拆封:
type Something1 struct { Thing string `json:"thing"` OtherThing int64 `json:"other_thing"` } type Something2 struct { Croc int `json:"croc"` Odile bool `json:"odile"` } type Unpacker struct { Data interface{} } func (u *Unpacker) UnmarshalJSON(b []byte) error { smth1 := &Something1{} err := json.Unmarshal(b, smth1) // no error, but we also need to make sure we unmarshaled something if err == nil && smth1.Thing != "" { u.Data = smth1 return nil } // abort if we have an error other than the wrong type if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok { return err } smth2 := &Something2{} err = json.Unmarshal(b, smth2) if err != nil { return err } u.Data = smth2 return nil }
http://play.golang.org/p/Trwd6IShDW