把整数格式化成固定长度的十六进制字符串,是 Go 开发里很常见的小需求,比如生成颜色值、协议字段,或者把某些 ID 统一成易读格式。这个场景下,很多人会先想到手动补零,但 Go 标准库其实已经给出了更直接的写法。下面就围绕 `fmt.Sprintf("%06x", num)` 说明它为什么适合做默认方案、它的输出规则是什么,以及遇到“必须严格 6 位”时该怎么处理。
Go 中最直接的写法
如果目标是把一个 int 转成小写、左补零、长度至少为 6 位的十六进制字符串,直接使用 fmt.Sprintf 即可:
package main
import "fmt"
func main() {
num := 12
hex := fmt.Sprintf("%06x", num)
fmt.Println(hex) // 输出: "00000c"
// 更多测试用例
fmt.Println(fmt.Sprintf("%06x", 0))// "000000"
fmt.Println(fmt.Sprintf("%06x", 255))// "0000ff"
fmt.Println(fmt.Sprintf("%06x", 16777215)) // "ffffff"
fmt.Println(fmt.Sprintf("%06x", 16777216)) // "1000000" ← 注意:超 6 位时自动扩展(见下方说明)
}
这也是 Go 里最符合直觉、最接近标准答案的写法,代码短,语义也很清楚。
`%06x` 到底表示什么
%06x 这个格式串可以拆开理解:

%x:按小写十六进制输出整数,比如12会得到"c";6:表示最小宽度为 6;0:表示当宽度不足时,在左侧补 0。
组合起来,%06x 的效果就是:把整数格式化成十六进制,不足 6 位就在左边补零。
对应的输出结果如下:
12→"00000c"255→"0000ff"16777215→"ffffff"
如果你的需求就是常见的 24 位颜色值或固定展示长度,这个格式已经足够覆盖大多数情况。
为什么有时不会严格保持 6 位
这里最容易误解的一点是:%06x 里的 6 表示的是最小宽度,不是“强制只能输出 6 位”。
也就是说,当十六进制结果本身已经超过 6 位时,fmt.Sprintf 不会帮你截断,而是会直接按真实长度输出。例如:
fmt.Println(fmt.Sprintf("%06x", 16777216)) // "1000000"
16777216 的十六进制是 1000000,一共 7 位,所以结果会自动扩展成 7 个字符,而不是被压回 6 位。
这点在处理颜色值、协议字段或需要严格长度约束的输出时尤其要注意。若你以为 %06x 会自动裁掉高位,最终结果就可能和预期不一致。
如果必须严格限制为 6 位
如果你的真实需求不是“至少 6 位”,而是严格保留 6 位十六进制,本质上通常意味着只取低 24 位。这时应该先做位掩码,再格式化:

hex := fmt.Sprintf("%06x", num&0xffffff) // 确保仅保留低 24 位
这样即使原始整数更大,输出时也只会基于低 24 位生成结果,更符合颜色值或固定字段的常见规则。
例如,0xffffff 这个掩码会保留最后 24 个二进制位,对应恰好 6 位十六进制表示。对于“必须是 6 位”的业务约束,这一步通常比事后截字符串更可靠,也更清晰。
大写输出与其他写法怎么选
如果你需要的是大写十六进制形式,可以把 %06x 改成 %06X:
255→"0000FF"
另外,也有人会考虑用 strconv.FormatInt(int64(num), 16) 先转成十六进制字符串,再手动补零。但这种方式通常要再配合类似下面的逻辑:
strings.Repeat("0", 6-len(s)) + s
问题在于,这种写法步骤更多,也更容易把边界条件分散到多处处理。相比之下,fmt.Sprintf 直接把“十六进制输出”和“左补零宽度”放进一个格式串里,表达更集中,也更符合 Go 的日常写法。
因此,除非你有非常特殊的性能或格式控制需求,否则在这个场景下,fmt.Sprintf("%06x", num) 仍然应该是首选方案。









