Go语言特定格式JSON反序列化遇空值问题求助
解决Go中JSON数组反序列化为空的问题
你的问题核心在于JSON结构和Go类型不匹配,咱们一步步拆解清楚:
1. 先明确你的JSON结构
你要解析的是一个长度为2的数组:
["Msg",{"cmd":"ack","id":"B81DA375B6C4AA49D262","ack":2,"from":"18094158994@c.us","to":"18099897215@c.us","t":1555446115}]
第一个元素是字符串"Msg",第二个是包含cmd/id等字段的对象。
2. 你的代码为什么失败?
你定义的SEND结构体是一个JSON对象类型(对应键值对结构),但你试图用它去反序列化一个JSON数组。Go的json包无法把数组映射到对象,所以反序列化后所有字段都保持零值,自然输出为空。
3. 解决方案:匹配JSON数组的Go类型
这里有两种常用方式来处理这种数组结构:
方法一:用[]interface{}接收,再做类型断言
这种方式简单直接,适合快速解析:
package main import ( "encoding/json" "fmt" ) type MSG struct { CMD string `json:"cmd"` ID string `json:"id"` ACK int `json:"ack"` FROM string `json:"from"` TO string `json:"to"` T int64 `json:"t"` } func main() { data := `["Msg",{"cmd":"ack","id":"B81DA375B6C4AA49D262","ack":2,"from":"18094158994@c.us","to":"18099897215@c.us","t":1555446115}]` // 定义数组类型接收整个JSON var response [2]interface{} err := json.Unmarshal([]byte(data), &response) if err != nil { fmt.Println("反序列化失败:", err) return } // 取出第一个元素(消息类型) msgType, ok := response[0].(string) if !ok { fmt.Println("消息类型格式错误") return } fmt.Println("消息类型:", msgType) // 取出第二个元素并转换为MSG结构体 msgDataBytes, err := json.Marshal(response[1]) if err != nil { fmt.Println("转换数据失败:", err) return } var msg MSG err = json.Unmarshal(msgDataBytes, &msg) if err != nil { fmt.Println("解析消息数据失败:", err) return } fmt.Println("消息详情:", msg) }
方法二:自定义UnmarshalJSON接口(更优雅)
如果需要频繁解析这种结构,推荐自定义一个类型并实现json.Unmarshaler接口,让解析逻辑更清晰:
package main import ( "encoding/json" "fmt" ) type MSG struct { CMD string `json:"cmd"` ID string `json:"id"` ACK int `json:"ack"` FROM string `json:"from"` TO string `json:"to"` T int64 `json:"t"` } // 定义匹配JSON数组的自定义类型 type MsgResponse struct { Type string // 对应数组第一个元素 Data MSG // 对应数组第二个元素 } // 实现json.Unmarshaler接口,自定义反序列化逻辑 func (r *MsgResponse) UnmarshalJSON(data []byte) error { // 先把JSON解析成数组 var arr [2]interface{} if err := json.Unmarshal(data, &arr); err != nil { return err } // 验证第一个元素是字符串 var ok bool r.Type, ok = arr[0].(string) if !ok { return fmt.Errorf("数组第一个元素不是字符串") } // 把第二个元素反序列化为MSG结构体 dataBytes, err := json.Marshal(arr[1]) if err != nil { return err } return json.Unmarshal(dataBytes, &r.Data) } func main() { data := `["Msg",{"cmd":"ack","id":"B81DA375B6C4AA49D262","ack":2,"from":"18094158994@c.us","to":"18099897215@c.us","t":1555446115}]` var response MsgResponse err := json.Unmarshal([]byte(data), &response) if err != nil { fmt.Println("反序列化失败:", err) return } fmt.Println("消息类型:", response.Type) fmt.Println("消息详情:", response.Data) fmt.Println("ACK值:", response.Data.ACK) }
运行结果
两种方法都会输出类似这样的内容:
消息类型: Msg 消息详情: {ack B81DA375B6C4AA49D262 2 18094158994@c.us 18099897215@c.us 1555446115}
内容的提问来源于stack exchange,提问作者Victor Medrano
相关产品推荐
相关产品推荐

