Go中如何反序列化内嵌JSON字符串的JSON对象?
解决内嵌JSON字符串的Go结构体反序列化问题
要处理这种内嵌JSON字符串的反序列化场景,你需要为Child类型实现json.Unmarshaler接口——默认JSON反序列化器无法直接将字符串类型的字段值映射到结构体类型。
具体实现
给Child结构体添加自定义的UnmarshalJSON方法,逻辑上先尝试直接解析为结构体,失败则转为先解析成字符串再二次反序列化:
import "encoding/json" type Child struct { A string `json:"a"` } type Main struct { Foo int `json:"foo"` Bar Child `json:"bar"` } // 为Child实现UnmarshalJSON接口 func (c *Child) UnmarshalJSON(data []byte) error { // 先尝试直接将字节解析为Child结构体(兼容bar是普通JSON对象的情况) temp := struct{ A string `json:"a"` }{} if err := json.Unmarshal(data, &temp); err == nil { return json.Unmarshal(data, c) } // 如果是JSON字符串,先解析成字符串,再将字符串内容反序列化为Child var jsonStr string if err := json.Unmarshal(data, &jsonStr); err != nil { return err } return json.Unmarshal([]byte(jsonStr), c) }
测试验证
用你的示例输入进行测试:
import "log" import "fmt" func main() { input := []byte(`{ "foo":1, "bar":"{\"a\":\"Hello\"}" }`) var mainObj Main if err := json.Unmarshal(input, &mainObj); err != nil { log.Fatalf("反序列化失败: %v", err) } fmt.Printf("反序列化结果: %+v\n", mainObj) // 输出:反序列化结果: {Foo:1 Bar:{A:Hello}} }
原理说明
默认情况下,JSON反序列化器会认为bar字段的值应该是Child对应的JSON对象(即{"a":"Hello"}),但你的输入中它是一个字符串包裹的JSON。自定义的UnmarshalJSON方法先尝试常规解析,失败则切换到字符串解析逻辑,把包裹的JSON字符串提取出来后再反序列化为Child结构体,完美适配这种嵌套场景。
内容的提问来源于stack exchange,提问作者fahrradflucht
相关产品推荐
相关产品推荐

