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

🚀 二、HTTP 示例对比

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

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

🧾 公共结构体定义:

go 复制代码
type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

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

go 复制代码
func handlerWithEncoderDecoder(w http.ResponseWriter, r *http.Request) {
    var user User
    if 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

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

💡 实际建议

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

🧪 curl 测试命令

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

📚 参考文档


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

相关推荐
IvanCodes6 小时前
Python 数据处理(十三):JSON、CSV 与数据序列化
开发语言·python
aramae8 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
qq_25183645710 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
郑州光合科技余经理11 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
知识分享小能手11 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
+VX:Fegn089511 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
阿里嘎多学长12 小时前
2026-09-20 GitHub 热点项目精选
开发语言·程序员·github·代码托管
weixin_3077791314 小时前
C++代码实现MATLAB中的ode23tb函数功能
开发语言·c++·算法·matlab
2601_9669496514 小时前
为什么量化回测中 for 循环比 DataFrame 慢三个数量级?从向量化原理讲起
开发语言·python·pandas·股票数据·quantdash
边境悍匪16 小时前
蜗牛学苑 Java 智能体学习 Day45|Knife4j+SpringBoot3、书城项目整合 MyBatis 思维导图复盘
java·开发语言·vue.js·学习·spring