使用Golang编写一个简单的JSON格式化工具 Go语言标准库美化输出

2次阅读

json.marshalindent 输出空字符串主因是传入 nil 指针结构体字段未导出(小写首字母),导致序列化结果为 {};需确保字段大写、非 nil、time.time 等类型已适配。

使用Golang编写一个简单的JSON格式化工具 Go语言标准库美化输出

json.MarshalIndent 为什么输出空字符串?

调用 json.MarshalIndent 返回空字节切片,大概率是传入了 nil 指针或未导出字段。go 的 JSON 序列化只处理首字母大写的导出字段,小写字段直接被忽略,结构体里全是 name String 这种?那结果就是 {}

  • 检查结构体字段是否以大写字母开头,比如改成 Name string
  • 确认传给 json.MarshalIndent 的不是 nil,也不是指向 nil 的指针(var p *MyStruct 然后直接传 p
  • 如果输入来自 map[string]Interface{},确保 key 是字符串、value 能被 JSON 编码(比如不能是 func()chan

如何让 json.MarshalIndent 输出可读的缩进而非 t

json.MarshalIndent 第二个参数是 prefix,第三个是缩进符——它不一定是 "t",可以是任意字符串,比如两个空格更符合多数团队规范。

  • json.MarshalIndent(v, "", " ") 替代默认的 "t",避免编辑器 tab 宽度不一致导致格式错乱
  • prefix 参数常被误留空字符串,其实它可以加行首标识,比如日志场景:json.MarshalIndent(v, ">>> ", " ") 输出每行带 >>>
  • 注意:缩进符若含换行符(如 "n "),会导致输出格式异常,标准库不校验这个

处理 time.Time 和自定义类型时 panic: json: unsupported type

直接传 time.Time 或自定义 struct 给 json.MarshalIndent 会触发 json: unsupported type 错误,因为它们没实现 json.Marshaler 接口

  • time.Time,推荐在结构体中用 string 字段 + 自定义 getter/setter,或嵌入实现了 MarshalJSON() 的包装类型
  • 快速补救:用 map[string]interface{} 中转,手动把 time.Time.format("2006-01-02T15:04:05Z") 赋值进去
  • 别试图在 MarshalJSON 方法里调用 json.MarshalIndent —— 会无限递归,改用 json.Marshal

命令行工具里怎么读 stdin 并格式化输出?

想写个类似 cat data.json | go-json-fmt 的小工具,核心是别用 os.Args 硬解析文件路径,优先读取 os.Stdin,再 fallback 到文件。

立即学习go语言免费学习笔记(深入)”;

  • io.ReadAll(os.Stdin) 获取原始字节,别用 bufio.Scanner —— 它默认 64KB 缓冲,大 JSON 直接 panic
  • 解码前先做最小校验:bytes.TrimSpace 去首尾空白,再看是否以 {[ 开头,避免把错误输入当 JSON 解析
  • 输出时用 fmt.print 而非 fmt.Println,否则末尾多一个空行,管道下游容易出问题

实际跑起来最常卡在字段不可导出和 time 处理上,这两处没报错但输出为空或 panic,得盯着数据源结构和类型定义看。

text=ZqhQzanResources