json.Marshal 从不 panic,只返回 error;真正导致崩溃的是忽略 error 后使用 nil 切片、空指针或类型断言失败,正确做法是立即检查并处理 error。
json.Marshal 会 panic?它其实不会很多人以为 json.Marshal 可能 panic,实际它**从不 panic**,而是返回 error。真正让你程序崩溃的,往往是忽略这个 error 后继续用 nil 的字节切片(比如传给 HTTP 响应或写文件),或在后续逻辑中触发空指针/类型断言失败。
json.Marshal 只在遇到不可序列化值时返回非 nil 错误,例如含 func、chan、未导出字段且无 json tag、循环引用等*json.UnsupportedTypeError 或 *json.InvalidUTF8Error 等,都实现了 error 接口,可直接判断recover() 拦截 json.Marshal —— 它根本不会抛出 panicjson.Marshal 错误的惯用写法Go 中标准做法是「检查 error,立刻处理」。常见错误是只打印日志却不终止流程,导致下游收到空数据或乱码。
data := struct {
Name string `json:"name"`
Age int `json:"age"`
Fn func() `json:"-"` // 不导出 + 无 tag → 会出错
}{
Name: "Alice",
Age: 30,
}
b, err := json.Marshal(data)
if err != nil {
// ✅ 正确:区分错误类型,做针对性响应
switch e := err.(type) {
case *json.UnsupportedTypeError:
log.Printf("无法序列化字段 %s: %v", e.Type.String(), e.Error())
http.Error(w, "响应数据构造失败", http.StatusInternalServerError)
return
case *json.InvalidUTF8Error:
log.Printf("字符串含非法 UTF-8: %v", e)
http.Error(w, "数据编码异常", http.StatusBadRequest)
return
default:
log.Printf("JSON 序列化未知错误: %v", err)
http.Error(w, "服务内部错误", http.StatusInternalServerError)
return
}
}
w.Header().Set("Content-Type", "application/json")
w.Write(b)
json.Marshal 返回 error?不是所有 Go 类型都能直译成 JSON。以下情况必然失败,且错误信息明确:
func、chan、complex64/complex128 类型字段(即使已导出)json:"..." tag;若加了 json:"-" 则跳过,不报错string、int、int32 等基本可比较类型(如 map[struct{X int}]string)json: unsupported value: encountered a cycle
json.Marshal 错误的实用技巧线上环境难复现循环引用或非法 UTF-8,建议在单元测试中主动构造边界 case。
reflect.ValueOf(v).Kind() == reflect.Func 提前过滤掉含函数字段的结构体(适合封
装自己的 SafeMarshal)utf8.Valid([]byte(s)) 预检,避免传入 json.Marshal 后才报错go test -v 并在测试中故意传入含 chan int 的结构体,确认错误分支被覆盖json.Marshal(nil) 是合法的,返回字面量 null,不会出错最常被忽略的是:错误处理后忘记 return,导致仍执行后续 w.Write(nil) —— 这会让客户端收到空响应而不报错,排查难度远大于直接返回 500。
# js
# json
# go
# golang
# 编码
# app
# 字节
# usb
# switch
# 为什么
# red
# String
# NULL
# 封装
# Error
# 字符串
# 结构体
# int
# 循环
# 指针
# 接口
# Struct
# 空指针
# 切片
# nil
# map
# kind
# http
# 的是
# 报错
# 序列化
# 这会
# 自己的
# 让你
# 都能
# 很多人
# 并在
# 而不
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Win11怎么设置默认浏览器Chrome_Windows11修改默认网页打开方式
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
php增删改查需要哪些扩展_开启mysqli或pdo扩展方法【说明】
如何使用Golang table-driven基准测试_多组数据测量函数效率
Win10如何更改电脑休眠时间_Windows10电源和睡眠选项调整
全球各国上班时间表外贸邮件时间
如何使用Golang捕获并记录协程panic_保证主程序稳定运行
Win11怎么更改鼠标指针方案_Windows11自定义鼠标光标样式与大小
Go 中实现 Python urllib.quote() 等效功能的正确方式
如何使用Golang实现文件追加操作_向已有文件追加数据
Python对象生命周期管理_创建销毁说明【指导】
Python对象比较与排序_集合使用说明【指导】
c++20的std::format怎么用 比printf更安全高效的格式化方法【详解】
Win10系统怎么查看端口状态_Windows10 CMD查看网络连接
Win11怎么清理C盘OneDrive缓存_Win11清理OneDrive缓存技巧【方法】
Win11如何关闭游戏模式 Win11禁用Xbox Game Bar录制【优化】
如何在Golang中使用log包输出不同级别日志_Golang log日志管理与分类
php订单日志怎么记录评价_php记录订单评价日志方法【方法】
windows如何修改文件默认打开方式_windows设置程序关联教程
Linux怎么禁止Root用户远程登录_Linux系统SSH加固与安全设置【教程】
c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】
Win11如何更改用户账户文件夹名称 Win11修改C:Users用户名【终极教程】
Win11怎么设置ipv4地址_Windows 11固定静态IP地址配置教程【详解】
php订单日志怎么在swoole写_php协程swoole写订单日志教程【教程】
Windows10电脑怎么设置文件权限_Win10安全选项卡所有者修改
Win11时间不对怎么同步_Win11自动校准互联网时间【设置】
如何使用Golang处理静态文件缓存_提高页面加载速度
如何优化Golang Web性能_Golang HTTP服务器性能提升方法
Python并发安全问题_资源竞争说明【指导】
C#如何在一个XML文件中查找并替换文本内容
c# 如何深拷贝和浅拷贝
Win11怎样安装网易云音乐_Win11安装网易云教程【步骤】
Win11文件扩展名怎么显示_Win11查看文件后缀名设置【基础】
网站体验不好=浪费钱:如何提升-用户体验效果差
Win11如何设置自动关机 Win11定时关机命令使用教程【技巧】
LINUX的SELinux是什么_详解LINUX强制访问控制系统的入门与配置
Win11怎么关闭系统提示音_Windows11声音方案设为无声教程
如何使用正则表达式批量替换重复的 *- 模式为固定字符串
Python邮件系统自动化教程_批量发送解析与模板应用
如何快速验证Golang安装是否成功_运行go version和hello world示例
如何在Golang中实现RPC异步返回_Golang RPC异步处理与回调方法
Win10如何更改网络连接_Windows10以太网属性IP配置
如何在Golang中写入XML文件_生成符合规范的XML数据
windows如何禁用驱动程序强制签名_windows高级启动设置指南
c++如何使用std::bind绑定函数参数_c++ 占位符std::placeholders使用【详解】
c# 在ASP.NET Core中管理和取消后台任务
Drupal 中 HTML 链接被双重转义导致渲染异常的解决方案
php删除数据怎么软删除_添加is_del字段标记删除【技巧】
Python 中将 ISO 8601 时间戳转换为日期并计算日期差值的完整教程
Windows10如何更改日期格式_Win10区域设置短日期修改
2026-01-01
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。