strconv.formatint 是最稳妥的任意进制(2–36)整数转字符串方法,支持 int64 及负数,需显式类型转换;超出 36 进制或 base62/58 等自定义编码须自行实现,注意符号、边界及字符映射。

用 strconv.FormatInt 快速转任意进制
Go 标准库提供了直接支持,不需要手写除基取余逻辑。strconv.FormatInt 是最常用、最稳妥的方式,适用于 int64 范围内的整数(包括负数)。
它接受三个参数:value(int64 类型)、base(2–36 的整数)、width 和 flag 不参与进制转换,所以只需关注前两个。
-
base为 2~36:合法;小于 2 或大于 36 会 panic,错误信息是strconv: illegal base - 负数会自动加负号,比如
strconv.FormatInt(-10, 2)返回"-1010" - 如果原数是
int(如int在 64 位系统上等价于int64),需显式转成int64,否则编译报错:cannot use … (type int) as type int64 in argument to strconv.FormatInt
处理 int 或 uint 类型时的类型转换陷阱
Go 对整数类型严格,strconv.FormatInt 只认 int64,strconv.FormatUint 只认 uint64。常见误用是直接传 int 变量。
正确做法:
- 对有符号整数:
strconv.FormatInt(int64(x), base) - 对无符号整数:
strconv.FormatUint(uint64(x), base) - 不要用
int64(x)强转uint值——会导致高位截断或溢出,例如uint32(0xffffffff)转成int64没问题,但若原值是uint64(0xffffffffffffffff),再转int64就会变负数
自定义进制(如 Base62、Base58)不能用 strconv
strconv.FormatInt 仅支持 2–36 进制,字符集固定为 0–9a–z(小写)。如果你需要 Base62(0–9A–Za–z)或 Base58(剔除易混淆字符),必须自己实现。
核心逻辑仍是除基取余,但需注意:
- 余数映射到自定义字符表,不是默认的
"0123456789abcdefghijklmnopqrstuvwxyz" - 负数需单独处理符号,因为 Base62 等编码通常只用于无符号场景
- 空输入或 base ≤ 1 要提前返回错误,避免死循环
- 推荐把字符表定义为
var base62Table = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",然后按索引查表
性能与内存:小数转字符串时别反复分配
每次调用 strconv.FormatInt 都会新建字符串,底层涉及内存分配。如果在热点路径(如高并发 ID 编码)中频繁调用,可考虑复用 []byte 缓冲或使用 fmt.Sprintf(但后者更慢且不推荐)。
更实际的优化点:
- 对固定进制(如 always base=36),可预计算字符表并内联逻辑,减少函数调用开销
- 避免在循环里重复调用
strconv.FormatInt(x, 36)处理同一数值多次——先算一次存变量 -
strconv版本已高度优化,除非压测证明是瓶颈,否则不必过早手动重写
真正容易被忽略的是:进制数超出 36 后没有标准库兜底,而自定义编码又常忽略边界情况(比如输入为 0 时是否返回空字符串或单个 '0'),这点在写 Base62 工具函数时务必单独测试。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











