问题陈述
使用 Go 的 json.Unmarshal 解码字符串时从消息系统中发现结果是map[string]interface{}而不是预期的结构类型(Somthing1 或 Somthing2),使得类型断言不可能。
根本原因
json.Unmarshal 函数,当解组到接口{}时,默认值已知类型,如 []interface{} 和 map[string]interface{}。在给定的代码中,接口变量输入接收表示未编组的 JSON 数据的 map[string]interface{},但 switch 语句尝试直接将其断言为 Somthing1 或 Somthing2。
解决方案
由于 JSON 本身并未解组到所需的结构中,因此有两个选项可以解决此问题问题:
1。从通用映射中检查和转换:
一种方法是检查 map[string]interface{} 并手动将数据解包到适当的结构类型中。但是,这需要仔细处理潜在错误并手动分配值。
2.使用自定义 JSON 解组器:
更简洁的解决方案是创建自定义 JSON 解组器来处理解组过程。此自定义解组器可以根据 JSON 数据识别正确的结构类型并相应地对其进行解组。以下是此类解组器的示例:
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 }
通过将此自定义解组器的实例传递给 json.Unmarshal,生成的 Data 字段将包含正确结构类型的解组数据,从而允许无缝类型断言.
以上是当使用 Go 的 `json.Unmarshal` 和 `interface{}` 时,如何有效地将 JSON 数据解组到特定的结构中?的详细内容。更多信息请关注PHP中文网其他相关文章!