当前位置: 首页 > news >正文

Go语言中json.RawMessage

在 Go 语言中,json.RawMessage 是标准库 encoding/json 包提供的一种类型,用于保存原始的 JSON 字节数据,避免在序列化/反序列化过程中被自动解析。它的核心作用是“延迟解析”或“保留原始 JSON 格式”,常用于处理动态 JSON 结构、嵌套 JSON 或需要手动控制解析时机的场景。

一、json.RawMessage 的定义

json.RawMessage 本质上是 []byte 的类型别名:

type RawMessage []byte

但它实现了 json.Marshalerjson.Unmarshaler 接口,因此在 JSON 处理时会被特殊对待——序列化时直接输出原始字节,反序列化时直接保存原始 JSON 字节而不解析。

二、核心用法场景

1. 保留原始 JSON 数据,避免自动解析

当 JSON 中某字段的结构不固定(例如动态类型、嵌套 JSON),可以用 json.RawMessage 暂存原始字节,后续再根据业务逻辑手动解析。

示例
假设有一个 JSON 数据,其中 data 字段的结构可能是对象、数组或其他类型:

{"type": "user","data": {"id": 1, "name": "Alice"}
}

{"type": "post","data": {"id": 100, "title": "Go 教程"}
}

json.RawMessage 保存 data 字段的原始 JSON:

package mainimport ("encoding/json""fmt"
)// 定义外层结构体,data 字段用 RawMessage 保存原始 JSON
type Response struct {Type string          `json:"type"`Data json.RawMessage `json:"data"` // 不自动解析,保留原始字节
}// User 和 Post 是 data 可能的结构
type User struct {ID   int    `json:"id"`Name string `json:"name"`
}type Post struct {ID    int    `json:"id"`Title string `json:"title"`
}func main() {// 示例 JSON 数据(user 类型)jsonStr := `{"type":"user","data":{"id":1,"name":"Alice"}}`// 反序列化到 Response,data 保留原始 JSON 字节var resp Responseif err := json.Unmarshal([]byte(jsonStr), &resp); err != nil {panic(err)}// 根据 type 字段手动解析 dataswitch resp.Type {case "user":var user Userif err := json.Unmarshal(resp.Data, &user); err != nil { // 手动解析 RawMessagepanic(err)}fmt.Printf("解析到用户:%+v\n", user) // 解析到用户:{ID:1 Name:Alice}case "post":var post Postjson.Unmarshal(resp.Data, &post)fmt.Printf("解析到文章:%+v\n", post)}
}
2. 嵌套 JSON 结构的序列化

当需要手动构造嵌套 JSON 时,json.RawMessage 可以直接嵌入原始 JSON 字节,避免多层结构体嵌套的繁琐。

示例
直接将原始 JSON 字符串作为字段值序列化:

package mainimport ("encoding/json""fmt"
)func main() {// 原始 JSON 字符串(作为嵌套数据)rawData := `{"key": "value", "num": 123}`// 构造外层结构体,嵌入 RawMessagedata := struct {Code int             `json:"code"`Msg  string          `json:"msg"`Data json.RawMessage `json:"data"` // 直接嵌入原始 JSON}{Code: 200,Msg:  "success",Data: json.RawMessage(rawData), // 转换为 RawMessage}// 序列化result, err := json.MarshalIndent(data, "", "  ")if err != nil {panic(err)}fmt.Println(string(result))
}

输出

{"code": 200,"msg": "success","data": {"key": "value","num": 123}
}

如果不用 json.RawMessage,直接用 string 类型保存 rawData,序列化后会带引号(作为字符串处理),不符合预期。

3. 避免循环引用导致的序列化错误

如果结构体中存在循环引用(如 A -> B -> A),直接序列化会报错。此时可以用 json.RawMessage 手动处理循环部分的 JSON 输出。

三、注意事项

  1. 类型转换json.RawMessage[]byte 可以直接转换(因为是类型别名):

    raw := json.RawMessage([]byte(`{"a":1}`))
    b := []byte(raw) // 合法
    
  2. 空值处理:未初始化的 json.RawMessagenil,序列化后为 null

  3. 解析校验:使用 json.Unmarshal 解析 json.RawMessage 时,需确保原始字节是有效的 JSON,否则会返回错误。

总结

json.RawMessage 的核心价值是保留 JSON 原始字节,延迟或手动控制解析,适用于:

  • 动态 JSON 结构(字段类型不固定)。
  • 嵌套 JSON 的直接嵌入。
  • 避免循环引用或复杂结构的自动解析问题。

通过它可以灵活处理 JSON 序列化/反序列化的细节,尤其在处理不确定结构的 JSON 数据时非常实用。

http://www.dtcms.com/a/549573.html

相关文章:

  • Pytorch常用函数学习摘录
  • 个人什么取消网站备案铭万做的网站怎么样
  • 2025-10-30 ZYZOJ Star(斯达)模拟赛 hetao1733837的record
  • 百胜中台×OceanBase:打造品牌零售降本增效的数字核心引擎,热门服饰、美妆客户已实践
  • 深度学习调试工具链:从PyTorch Profiler到TensorBoard可视化
  • 不可变借用的规则与限制: 从只读语义到零拷贝架构的 5 000 字深潜
  • 专题三 之 【二分查找】
  • C++进阶: override和final说明符-----继承2中重写的确认官和刹车(制动器)
  • 数据科学每日总结--Day7--数据库
  • opencv 学习: 01 ubuntu20.04 下 opencv 4.12.0 源码编译
  • 满足“国六”标准的通用型故障诊断仪:Q-OBD
  • 上海专业建站公湖南网站建设设计
  • 智慧时空大数据平台:释放时空信息数据价值
  • 线程基本概念
  • MySQL MDL锁阻塞DDL 导致复制线程卡住
  • 智慧管理,赋能美容院新未来
  • Flink做checkpoint迟迟过不去的临时解决思路
  • 网站注册 优帮云wordpress首页静态化
  • [人工智能-大模型-115]:模型层 - 用通俗易懂的语言,阐述神经网络为啥需要多层
  • Actix Web 不是 Nginx:解析 Rust 应用服务器与传统 Web 服务器的本质区别
  • pdf文件上传下载记录
  • 辽阳网站设计中国建设银行的网站.
  • 2. WPF程序打包成一个单独的exe文件
  • 东软专业力考试--Java Web 开发基础
  • 8方向控制圆盘View
  • js中Map和对象{}的区别
  • 基于python构建的低温胁迫实验
  • 服装公司网站修改wordpress后台登陆
  • 2025 Avalonia 技术全景:从版本迭代到生产级落地的成熟之路
  • 做网站却不给客户源代码奥迪互动平台