You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:00:50