关于go vet对Sprintf带编号格式参数检查的疑问
关于go vet对Sprintf检查的特殊行为解析
核心原因
go vet对fmt.Sprintf的校验逻辑聚焦在格式化字符串中明确引用的参数是否存在,以及普通无索引占位符的参数数量匹配性,不会校验「未被格式化字符串引用的多余参数」——这就是case 2不触发违规的关键。
分场景拆解
case 1:
fmt.Sprintf("%[1]s%[2]s", "foo")
格式化字符串里显式引用了索引为2的参数,但实际只传入了1个参数,vet能检测到「引用的参数不存在」,因此触发违规。case 2:
fmt.Sprintf("%[1]s", "foo", "bar")
格式化字符串仅引用了索引为1的参数,且该参数确实存在。vet不会校验未被引用的多余参数(这里的"bar"),所以不会触发违规。case 3:
fmt.Sprintf("%s", "foo", "bar")
普通%s占位符默认按顺序匹配参数,第一个%s对应"foo",但多传的"bar"没有对应的占位符。vet对无索引的占位符会严格校验参数数量匹配性,因此触发违规。
覆盖该场景的方案
如果需要检测「未被引用的格式化参数」这类场景,go vet本身不支持,但可以使用更严格的lint工具,比如staticcheck的ST1013规则,它会扫描所有未被格式化字符串使用的参数,无论是否用了显式索引。
内容的提问来源于stack exchange,提问作者Honza P.
相关产品推荐
相关产品推荐

