打印函数
迁移参考
本页为 Print 系列函数(已在早期版本移除)的迁移指南。如需格式化 JSON,请使用 Prettify 或标准库兼容的 MarshalIndent。
API 变更说明
Print、PrintPretty、PrintE、PrintPrettyE 已从库中移除,不再提供。请使用以下替代方案。
替代方案
打印紧凑 JSON
使用 fmt.Println + EncodeWithConfig(推荐)或 Marshal:
data := map[string]any{"name": "Alice", "age": 30}
s, err := json.EncodeWithConfig(data)
if err != nil {
log.Fatal(err)
}
fmt.Println(s)
// 输出:{"age":30,"name":"Alice"}
// 或者使用 Marshal([]byte 输出)
b, err := json.Marshal(data)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))Encode 已废弃
json.Encode 已标记为废弃(与 EncodeWithConfig 功能等价),将在未来主版本移除。新代码请使用 EncodeWithConfig 或 Marshal。
打印格式化 JSON
使用 fmt.Println + EncodePretty:
s, err := json.EncodePretty(data)
if err != nil {
log.Fatal(err)
}
fmt.Println(s)
// 输出:
// {
// "age": 30,
// "name": "Alice"
// }打印 JSON 字符串(美化已有 JSON)
使用 Prettify:
pretty, err := json.Prettify(`{"name":"Alice","age":30}`)
if err != nil {
log.Fatal(err)
}
fmt.Println(pretty)
// 输出:
// {
// "name": "Alice",
// "age": 30
// }使用 Processor 打印
p, err := json.New()
if err != nil {
panic(err)
}
defer p.Close()
// 编码并打印(推荐 EncodeWithConfig;Encode 已废弃)
s, err := p.EncodeWithConfig(data)
if err != nil {
log.Fatal(err)
}
fmt.Println(s)
// 格式化打印
pretty, err := p.EncodePretty(data)
if err != nil {
log.Fatal(err)
}
fmt.Println(pretty)格式化工具对照
按「输入是 Go 值还是 JSON 文本」选择工具:
| 函数 | 输入 | 输出 | 典型用途 |
|---|---|---|---|
Marshal(v, cfg...) | Go 值 | []byte 紧凑 | 标准库签名,最通用 |
EncodeWithConfig(v, cfg...) | Go 值 | string 紧凑 | 推荐入口(可带配置) |
EncodePretty(v, cfg...) | Go 值 | string 缩进 | 直接编码并美化 |
MarshalIndent(v, prefix, indent) | Go 值 | []byte 缩进 | 标准库签名,兼容旧代码 |
Prettify(jsonStr, cfg...) | JSON 文本 | string 缩进 | 美化已有 JSON 文本 |
Compact(dst, src) | JSON 文本 | 写入 *bytes.Buffer | 压缩已有文本 |
CompactString(jsonStr) | JSON 文本 | string 紧凑 | 压缩已有文本(免 buffer) |
Indent(dst, src, prefix, indent) | JSON 文本 | 写入 *bytes.Buffer | 重排缩进 |
HTMLEscape(dst, src) | JSON 文本 | 写入 *bytes.Buffer | 转义 < > & |
NewEncoder(w) + SetIndent | Go 值 | 写入 io.Writer | 流式输出(文件/网络) |
三步选型
- 输入是 Go 值:要
[]byte用Marshal,要string用EncodeWithConfig;需要缩进时分别换MarshalIndent、EncodePretty - 输入已是 JSON 文本:美化用
Prettify,压缩用CompactString;需要与标准库签名完全一致时用 buffer 版Compact/Indent - 输出到流(文件/网络):
NewEncoder+SetIndent逐条写出,避免整块拼大字符串
自定义缩进
EncodePretty 默认两空格缩进。需要其他缩进时用 Config.Pretty + Config.Indent,或直接用标准库签名的 MarshalIndent:
package main
import (
"fmt"
"github.com/cybergodev/json"
)
func main() {
data := map[string]any{"name": "Alice", "age": 30}
// 方式一:标准库签名 MarshalIndent(prefix 通常留空)
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(b))
// 输出:
// {
// "age": 30,
// "name": "Alice"
// }
// 方式二:EncodePretty + 配置(制表符缩进)
cfg := json.DefaultConfig()
cfg.Pretty = true
cfg.Indent = "\t"
s, err := json.EncodePretty(data, cfg)
if err != nil {
panic(err)
}
fmt.Println(s)
}TIP
json.PrettyConfig() 是现成预设:默认配置 + Pretty: true + 两空格缩进,等价于 EncodePretty 的默认行为。
处理已有 JSON 文本
手里已经是 JSON 文本(如日志、接口返回)时,用格式化函数原地转换,无需再走一遍结构体:
package main
import (
"bytes"
"fmt"
"github.com/cybergodev/json"
)
func main() {
pretty := "{\n \"name\": \"Alice\",\n \"age\": 30\n}"
// 压缩:去除所有非必要空白
var compact bytes.Buffer
if err := json.Compact(&compact, []byte(pretty)); err != nil {
panic(err)
}
fmt.Println(compact.String())
// 输出:{"name":"Alice","age":30}
// 免 buffer 版:CompactString 直接返回字符串
s, err := json.CompactString(pretty)
if err != nil {
panic(err)
}
fmt.Println(s)
// 重排:换一种缩进风格
var reindented bytes.Buffer
if err := json.Indent(&reindented, []byte(pretty), "", "\t"); err != nil {
panic(err)
}
fmt.Println(reindented.String())
// 输出:
// {
// "name": "Alice",
// "age": 30
// }
}HTML 安全转义
HTMLEscape 与标准库签名一致:把 JSON 文本中的 <、>、&、U+2028、U+2029 转义为 \u00XX 形式,防止 JSON 内嵌 HTML 时被浏览器误解析。它做的是字符级转义,不重新编码、不改空白:
package main
import (
"bytes"
"fmt"
"github.com/cybergodev/json"
)
func main() {
src := []byte(`{"html":"<b>bold</b>","url":"a&b"}`)
var buf bytes.Buffer
json.HTMLEscape(&buf, src)
out := buf.String()
fmt.Println(out)
// 输出的引号内不再有裸露的 <、>、&,
// 它们分别被替换为 \u00XX 形式的转义序列,其余内容原样保留
}什么时候需要手动转义?
Marshal/EncodeWithConfig 默认已开启 HTML 转义(Config.EscapeHTML: true),编码产物本身是安全的。HTMLEscape 主要用于处理外部拿到的 JSON 文本——比如要把第三方返回的 JSON 原样内嵌到 HTML 页面时,先过一遍再输出。
流式输出到 Writer
写文件或网络流时,用 NewEncoder(标准库签名)避免整块拼字符串:
package main
import (
"os"
"github.com/cybergodev/json"
)
func main() {
type Item struct {
ID int `json:"id"`
Name string `json:"name"`
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
for _, item := range []Item{{1, "Alice"}, {2, "Bob"}} {
if err := enc.Encode(item); err != nil {
panic(err)
}
}
// 输出:
// {
// "id": 1,
// "name": "Alice"
// }
// {
// "id": 2,
// "name": "Bob"
// }
}Encoder.Encode 与标准库一致,每条记录后自动换行——逐条输出日志、写 JSONL 文件都很自然。
完整示例
package main
import (
"fmt"
"github.com/cybergodev/json"
"log"
)
func main() {
data := map[string]any{
"users": []any{
map[string]any{"id": 1, "name": "Alice"},
map[string]any{"id": 2, "name": "Bob"},
},
"total": 2,
}
// 紧凑输出(Encode 已废弃,推荐 EncodeWithConfig)
compact, err := json.EncodeWithConfig(data)
if err != nil {
log.Fatal(err)
}
fmt.Println(compact)
// 格式化输出
pretty, err := json.EncodePretty(data)
if err != nil {
log.Fatal(err)
}
fmt.Println(pretty)
}