fmt.Printf动词需严格匹配变量类型,否则运行时panic;%d仅用于整数,%f/%g/%e专用于浮点数,%s仅接受string或[]byte,%t只认bool,%c接收rune,结构体用%v/%+v/%#v区分输出格式,修饰符语义因动词而异,构造字符串应优先用fmt.Sprintf而非fmt.Printf。

fmt.Printf 的动词(verb)不是越多越好,关键是匹配变量类型和输出意图。用错动词会 panic 或输出不可预期的内容,比如 %d 打 float64、%s 打 struct、%f 打 int 都会出错。
怎么选动词:按变量类型对号入座
动词选错是 runtime panic 的高频原因,不是语法错误,编译期发现不了。
-
%d只用于整数类型(int,int64,uint等),不能用于float64或string -
%f,%g,%e专用于浮点数,传整数会报fmt.Printf: %f verb not allowed for integer -
%s仅接受string或[]byte;传 struct 默认只输出{},不是字段内容 -
%t只认bool,传字符串如"true"会输出%!t(string=true) -
%c接收的是 rune/uint32(Unicode 码点),不是字符串,fmt.Printf("%c", "a")会 panic
结构体输出:%v %+v %#v 三个最常用的区别
调试时看结构体,这三个动词行为差异明显,混用会导致信息缺失或冗余。
-
%v:默认格式,字段值按顺序输出,无字段名,如{42 true} -
%+v:带字段名,适合快速确认字段赋值是否正确,如{ID:42 Active:true} -
%#v:输出 Go 语法字面量,含包名和类型,适合生成可复用的测试数据,如main.User{ID:42, Active:true} - 三者都不触发自定义
String()方法,只有%v在类型实现了fmt.Stringer时才调用它
精度和宽度修饰符:语义因动词而异
修饰符不是通用的,同一组 .2 对 %s 和 %f 含义完全不同。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
-
%.2s:截取前 2 个字符("hello"→"he") -
%.2f:保留 2 位小数(3.14159→3.14) -
%6s:总宽至少 6,右对齐,不足补空格;%-6s是左对齐 -
%06d:整数不足 6 位时前面补 0(42→000042) -
%q对字符串加双引号并转义("a b"→"a\nb"),适合日志,不适合 UI 展示
fmt.Printf vs fmt.Sprintf:别在需要字符串的地方硬写到 stdout
函数用途错配是隐蔽 bug 源,尤其在拼接 SQL、HTTP header、JSON key 等场景。
立即学习“go语言免费学习笔记(深入)”;
- 要输出到终端或日志文件:用
fmt.Printf或fmt.Println - 要构造一个字符串供后续使用(比如传给
http.Header.Set):必须用fmt.Sprintf,fmt.Printf不返回值 - 高频循环中拼接字符串,
fmt.Sprintf会分配内存,应改用strings.Builder+fmt.Fprint -
fmt.Print("key=", k, ", val=", v)看似等价于fmt.Printf("key=%v, val=%v", k, v),但在并发日志中可能被其他 goroutine 的输出打断,导致错乱
%#v 和 %+v 这类“增强型”动词在嵌套结构体或指针上的表现——它们不会递归展开内部字段,除非每个嵌套类型也实现了 fmt.Stringer。

















