easyjson需正确注释、生成并调用:结构体上方独占一行写//easyjson:json,执行easyjson -all file.go生成file_easyjson.go,导入github.com/mailru/easyjson/json,并调用json.Marshal或结构体的MarshalJSON()方法,禁用encoding/json。

easyjson 能显著提升 Go JSON 性能,但不是“装了就能用”,它依赖正确的生成流程和调用方式。跳过注释、忽略生成文件或混用标准库接口,都会让优化失效。
结构体必须加 //easyjson:json 注释
这个注释不是可选的文档说明,而是 easyjson 工具识别目标结构体的唯一标记。它必须独占一行,且紧贴结构体定义上方(中间不能有空行或其它语句)。
- ✅ 正确写法:
//easyjson:json type User struct { ID int `json:"id"` Name string `json:"name"` } - ❌ 错误写法:注释写在结构体内、写成
// easyjson:json(多了空格)、或和type写在同一行 - 不加这行,
easyjson -all xxx.go会静默跳过该结构体,生成文件里没有对应方法,运行时仍走encoding/json的反射路径
生成命令要指定源文件,且需 import github.com/mailru/easyjson/json
easyjson 不是运行时插件,它把逻辑编译进你的代码。所以生成后,你项目里必须显式引入它的运行时包,否则 easyjson.Marshal 或 UnmarshalJSON 调用会报错未定义。
- 生成命令示例:
easyjson -all user.go(注意不是go run easyjson...) - 生成后会在同目录产出
user_easyjson.go,这个文件必须被go build编译进去 - 任何使用
easyjson功能的文件,都得有:import "github.com/mailru/easyjson/json" - 漏掉 import 会导致编译失败,错误信息类似:
undefined: easyjson.Marshal
别再用 json.Marshal 和 json.Unmarshal
生成完代码,如果继续调用标准库函数,等于白忙一场——所有优化都被绕过了。必须切换到 easyjson 提供的入口,或直接调用结构体上生成的方法。
- ✅ 推荐方式一(显式调用生成方法):
data, err := user.MarshalJSON()—— 零分配、无反射,最快 - ✅ 推荐方式二(统一入口):
data, err := json.Marshal(user)—— 这个json是 easyjson 的包,不是标准库 - ❌ 危险操作:仍写
json.Marshal(user)且 import 的是"encoding/json",性能毫无改善 - 反序列化同理:
json.Unmarshal(data, &user)必须来自github.com/mailru/easyjson/json,不能是标准库
指针字段和嵌套结构体默认支持,但 map[string]interface{} 仍慢
easyjson 对结构体字段类型做静态分析,所以 *string、[]User、map[string]User 都能生成高效代码。但它无法为动态类型生成专用逻辑。
- ✅
type Config struct { Data map[string]User }—— 可优化,因为 key/value 类型已知 - ❌
type Config struct { Data map[string]interface{} }—— 仍走泛化解析,性能退化回标准库水平 - 嵌套结构体只要每个层级都加了
//easyjson:json,就能全链路优化;漏一个,断点之后全靠反射兜底 - 生成代码里会包含大量
unsafe.String和预分配切片,所以不要手动修改*_easyjson.go文件
最容易被忽略的一点:生成的 *_easyjson.go 文件是构建产物,但必须提交进 Git。CI/CD 流程里如果只跑 go build 不先执行 easyjson 命令,就会编译失败或降级到标准库——这事在团队协作中发生过多次。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











