fmt.printf 是唯一解析格式动词的函数;其他 print 系列不处理 %s、%d,仅拼接字符串;%+v 适合调试结构体字段值与名称,%#v 输出可复现的 go 字面量;数字格式需注意类型匹配与修饰符顺序;写文件必须用 fmt.fprintf 并检查错误,高频写入应配合 bufio 缓冲。

fmt.Printf 是唯一真正解析格式动词的函数
别用 fmt.Print 或 fmt.Println 做格式化输出——它们根本不处理 %s、%d 这类动词,只会把整个字符串当普通文本拼接输出。
常见错误现象:fmt.Println("name: %s, age: %d", "Alice", 30) 输出结果是 name: %s, age: %d Alice 30,而不是你想要的替换效果。
-
fmt.Printf是 Go 中唯一接受并解析格式动词的函数;其他 Print 系列只做类型转字符串 + 空格/换行拼接 -
fmt.Printf不自动换行,必须手动加\n,否则连续调用会挤在同一行 - 参数个数必须与格式动词数量严格匹配,否则运行时 panic(比如传 2 个参数但写了 3 个
%v)
结构体调试该用 %+v 还是 %#v
选错动词会让结构体输出信息缺失或冗余,直接影响排查效率。
%v 只输出字段值:{123 "foo" true} —— 没字段名,看不出哪个是 ID、哪个是 Name;
%+v 带字段名:{ID:123 Name:"foo" Active:true} —— 适合确认赋值是否符合预期;
%#v 输出可直接复制进代码的 Go 字面量:main.User{ID:123, Name:"foo", Active:true} —— 含包路径和类型,对 nil 切片或 map 明确输出 nil,而 %v 可能只显示 [] 或 {},容易误判为空集合。
- 日常日志和调试优先用
%+v,兼顾可读性和简洁性 - 需要复现数据或写测试用例时用
%#v - 避免在生产日志中无脑用
%#v,它可能暴露内部类型路径,增加日志体积
数字补零、进制和宽度修饰符怎么写才不 panic
%b、%x、%o 只接受整数类型;传 float64 或 string 会直接 panic。
补零不是加个 2 就行:%02d 表示“至少两位,不足补零”,而 %2d 补的是空格;负数如 -5 用 %03d 才得 -05。
十六进制带前缀用 %#x(%#b 无效);%#06x 表示总宽至少 6 字符(含 0x),例如 0x00ff;二进制补 8 位写成 %08b,但它补的是字符数,不是“保证 8 bit”——对负数按补码输出,通常不符合预期。
-
%f默认 6 位小数,要控制精度写%.2f,不能写成%2f -
%q适合安全转义字符串,比如fmt.Printf("%q", "a\nb")→"a\nb" - 所有宽度/精度修饰符顺序固定:标志(如
-左对齐)、宽度、精度(仅浮点/字符串适用)、动词
写文件必须用 fmt.Fprintf,且不能漏错误检查
fmt.Printf 固定输出到终端,写文件必须换函数。第一个参数必须是实现了 io.Writer 接口的对象,比如 *os.File 或 *bufio.Writer。
典型错误:忽略 os.Create 返回的 err,导致后续 fmt.Fprintf 对 nil 文件句柄静默失败,日志没写进去还不报错。
- 正确姿势:
file, err := os.Create("log.txt"); if err != nil { /* handle */ },再调用fmt.Fprintf(file, "id=%06d, name=%q\n", id, name) - 高频写入务必套
bufio.NewWriter,否则每次fmt.Fprintf都触发系统 write,性能断崖式下降 - 写完记得
buf.Flush()或file.Close(),否则缓冲区内容可能丢失
最常被忽略的是缓冲区 flush 和错误链路完整性——哪怕 os.Create 成功了,fmt.Fprintf 仍可能因磁盘满、权限不足等失败,不检查返回值就等于放弃容错能力。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











