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

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,否则末尾多一个空行,管道下游容易出问题










