json.Compact不是压缩而是去格式化,它仅移除JSON中的空格、换行和缩进等空白字符,将美化格式转为单行紧凑形式,不改变语义也不使用gzip等算法,故不减小实际字节体积。

为什么 json.Compact 不是“压缩”,而是“去格式化”
json.Compact 不会减小 JSON 字节大小(比如不进行 gzip 或 base64 编码),它只是移除空格、换行和缩进等空白字符,把美化后的 JSON 变成单行紧凑格式。这在传输或日志记录时能省几 KB,但对大 JSON 效果有限;真要压缩得用 gzip 流式处理。
常见误用是把它当“JSON 压缩函数”调用后发现体积没变小——其实是预期错了。它解决的是“去掉人为添加的空白”,不是“算法压缩”。
怎么正确调用 json.Compact
它接收两个参数:dst(输出目标 []byte 切片)和 src(原始 JSON 字节切片),返回 error。注意:它**不会自动分配 dst 内存**,必须提前分配足够空间(通常用 make([]byte, 0, len(src)) 预估容量)。
- 原始 JSON 必须是语法合法的,否则返回
json.SyntaxError - 如果
dst容量不足,会 panic(因为内部用dst = append(dst, ...)) - 推荐写法:
dst := make([]byte, 0, len(src)),再传入json.Compact(dst, src)
src := []byte(`{
"name": "Alice",
"age": 30
}`)
dst := make([]byte, 0, len(src))
dst, err := json.Compact(dst, src)
// dst == []byte(`{"name":"Alice","age":30}`)
和 json.Marshal 混用时容易踩的坑
别在 json.Marshal 后直接丢给 json.Compact——虽然可行,但多了一次内存拷贝。更高效的做法是:先用 json.Marshal 得到字节,再 compact;或者用 bytes.Buffer + json.NewEncoder 配合自定义写入器(但复杂度上升)。
-
json.Marshal默认输出紧凑格式,所以多数情况下你根本不需要json.Compact - 只有当你拿到的是别人生成的带缩进 JSON(比如调试输出、HTTP 响应体、配置文件读取结果),才需要它
- 若源数据来自
json.Indent,那json.Compact是它的天然逆操作
性能与兼容性注意事项
json.Compact 是纯内存扫描,时间复杂度 O(n),没有反射、不触发 GC 分配(只要 dst 容量够),非常轻量。但它不处理 Unicode 转义、不验证字段名重复、也不关心数字精度——这些都由原始 JSON 的合法性决定。
- Go 1.1+ 全版本支持,无兼容问题
- 不能用于流式处理(比如边读 HTTP body 边 compact),必须持有完整字节切片
- 对含注释或尾随逗号的 JSON 会报错——它只接受标准 JSON,不兼容 JSON5 或 YAML
真正要注意的点只有一个:别忘了预分配 dst,也别指望它替代 gzip。其他时候,它就是个安静、可靠、做一件事的小工具。


















