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

Go 中 `json.NewEncoder/Decoder` 与 `json.Marshal/Unmarshal` 的区别与实践

Go 中 json.NewEncoder/Decoderjson.Marshal/Unmarshal 的区别与实践(HTTP 示例)

在 Go 中处理 JSON 有两种主要方式:使用 json.Marshal/Unmarshal 和使用 json.NewEncoder/Decoder。它们都能完成 JSON 的序列化与反序列化,但使用场景和优势略有不同。


🌱 一、整体概念对比

功能json.Marshal / json.Unmarshaljson.NewEncoder / json.NewDecoder
输入输出[]byte / stringio.Writer / io.Reader
性能一次性读写,适合小数据流式处理,适合大数据、网络请求体
易用性简洁直观,适合内存中的 JSON 数据可处理流式数据、更适合 HTTP 读写场景
典型应用JSON API 响应构建、配置文件加载等HTTP 请求/响应处理、文件流读取

🚀 二、HTTP 示例对比

我们用两个示例分别展示:

  1. json.NewEncoder/Decoder:直接读写 http.Request.Bodyhttp.ResponseWriter
  2. json.Marshal/Unmarshal:先读完整体,再解析和返回

🧾 公共结构体定义:

type User struct {ID    int    `json:"id"`Name  string `json:"name"`Email string `json:"email"`
}

🧪 方法一:使用 json.NewDecoderjson.NewEncoder

func handlerWithEncoderDecoder(w http.ResponseWriter, r *http.Request) {var user Userif err := json.NewDecoder(r.Body).Decode(&user); err != nil {http.Error(w, "invalid json", http.StatusBadRequest)return}response := map[string]interface{}{"status": "received","user":   user,}w.Header().Set("Content-Type", "application/json")if err := json.NewEncoder(w).Encode(response); err != nil {http.Error(w, "encode error", http.StatusInternalServerError)}
}

🧪 方法二:使用 json.Unmarshaljson.Marshal

func handlerWithMarshal(w http.ResponseWriter, r *http.Request) {bodyBytes, err := io.ReadAll(r.Body)if err != nil {http.Error(w, "read error", http.StatusInternalServerError)return}var user Userif err := json.Unmarshal(bodyBytes, &user); err != nil {http.Error(w, "invalid json", http.StatusBadRequest)return}response := map[string]interface{}{"status": "received","user":   user,}w.Header().Set("Content-Type", "application/json")jsonData, err := json.Marshal(response)if err != nil {http.Error(w, "encode error", http.StatusInternalServerError)return}w.Write(jsonData)
}

⚖️ 三、对比总结

对比点Encoder/DecoderMarshal/Unmarshal
使用便捷性可直接对接 HTTP 输入输出流需要读取/写入中间变量 []byte
适合大数据✅ 是(流式处理)❌ 需一次性加载全部数据
性能优势节省内存,特别适合大请求/响应适合结构简单或数据量小的应用
调试方便较复杂(不便打印中间数据)中间变量可供调试、日志记录

💡 实际建议

  • 接收请求体(尤其大数据或长连接):建议使用 json.NewDecoder
  • 返回响应数据(动态生成):建议使用 json.NewEncoder
  • 处理缓存、小数据、临时结构体转换:使用 json.Marshal/Unmarshal 更方便

🧪 curl 测试命令

curl -X POST http://localhost:8080/encoder \-H "Content-Type: application/json" \-d '{"id": 1, "name": "Alice", "email": "alice@example.com"}'

📚 参考文档

  • encoding/json 包官方文档
  • Go Web 编程最佳实践

希望这篇文章能帮助你理解 json.Marshal/Unmarshaljson.NewEncoder/Decoder 的差异,并选择适合你项目场景的方式。

http://www.xdnf.cn/news/734761.html

相关文章:

  • C++学习-入门到精通【10】面向对象编程:多态性
  • LangChain表达式 (LCEL)
  • C语言实现对哈希表的操作:插入新键值对与删除哈希表中键值对
  • 哪些岗位最易被AI替代?
  • Docker设置代理
  • ros2工程在普通用户下正常编译但root下编译无法成功也不会自动停止
  • RAG混合检索:倒数秩融合RRF算法
  • 零硬件成本玩转嵌入式通信!嵌入式仿真实验教学平台解锁STM8S串口黑科技
  • 对COM组件的调用返回错误 HRESULT E_FAIL
  • Linux操作系统之进程(四):命令行参数与环境变量
  • 统计C盘各种扩展名文件大小总和及数量的PowerShell脚本
  • << C程序设计语言第2版 >> 练习 1-23 删除C语言程序中所有的注释语句
  • Python基于Django的校园打印预约系统(附源码,文档说明)
  • 天拓四方工业互联网平台赋能:地铁电力配电室综合监控与无人巡检,实现效益与影响的双重显著提升
  • URL编码次数差异分析:一次编码 vs 二次编码
  • 【动手学深度学习】2.4. 微积分
  • Python中openpyxl库的基础解析与代码实例
  • NIO----JAVA
  • API:解锁网络世界的无限可能
  • Leetcode 340. 至多包含 K 个不同字符的最长子串
  • Java并发
  • [特殊字符] 超强 Web React版 PDF 阅读器!支持分页、缩放、旋转、全屏、懒加载、缩略图!
  • Elasticsearch的写入流程介绍
  • vscode实时预览编辑markdown
  • 树莓派安装openwrt搭建软路由(ImmortalWrt固件方案)
  • <3>, 常用控件
  • wheelgames
  • C++17新特性 类型推导
  • 虚拟化数据恢复—XenServer虚拟机虚拟磁盘文件丢失的数据恢复案例
  • 集成测试 maestro-我的第一个flow以及第一次云端测试