目录
1. 官方包
是的,strconv 是 Go 语言的官方标准库包。
2. 支持版本
- 引入版本:Go 1.0
- 支持版本:Go 1.0 开始一直支持至今
3. 官方说明
func FormatUint
func FormatUint(i uint64, base int) string
英文说明:
FormatUint returns the string representation of i in the given base, for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z' for digit values >= 10.
中文翻译:
FormatUint返回给定基数中i的字符串表示,对于2<=base<=36。对于大于等于10的数字值,结果使用小写字母“a”到“z”。
4. 作用
将 64 位无符号整数转换为指定进制的字符串表示。
具体功能:
- 输入:无符号整数 i (uint64 类型) 和进制 base(int 类型)
- 输出:该整数在指定进制下的字符串形式
- 支持的进制:2-36(二进制到三十六进制)
核心作用:无符号数字转字符串的进制转换工具。
5. 实现原理
核心算法:
- 进制转换算法 - 使用 "除基取余法"
- 不断用目标进制除无符号整数,记录余数
- 余数按逆序排序即为转换结果
- 字符映射 - 将数字转换为字符
- 0-9 → '0'-'9'
- 10-35 → 'a'-'z'(小写字母)
实现步骤
1. 处理特殊情况(0值)
2. 循环:i /= base, 记录 i % base
3. 将余数转换为对应字符
4. 反转字符序列得到最终字符串
优化策略
- 预分配缓冲区 - 避免频繁内存分配
- 位运算优化 - 对2的幂次进制使用位运算
- 小整数优化 - 对小数值使用查表法
- 无符号优化 - 无需处理负数、简化逻辑
本质:经典进制转换算法 + 字符编码映射,针对无符号整数优化。
6. 推荐使用场景和不推荐使用场景
| 场景类型 | 推荐使用 | 不推荐使用 |
| 无符号整数转换 | 处理ID、计数器、哈希值等无符号数据 | 需要处理复数的情况 |
| 进制转换 | 二进制、八进制、十六进制 | 十进制转换(用 strconv.Itoa 更简洁) |
| 性能要求 | 高频转换场景(标准库优化好) | 一次性转换且对性能不敏感 |
| 数据范围 | 需要处理 uint64 范围的大整数 | 只处理小整数(int 范围) |
| 进制范围 | 2-36 进制转换 | 超出 36 进制的特殊需求 |
| 错误处理 | 需要严格错误检查的场景 | 简单场景(用 fmt.Sprintf 更直观) |
| 内存使用 | 需要控制内存的场景 | 临时调试输出 |
| 代码可读性 | 明确表达无符号转换意图 | 简单格式化(用 fmt 包更清晰) |
| 符号处理 | 确保数据为非负数 | 可能为负数的数据(用 FormatInt) |
7. 使用场景示例
示例1:官方示例
func main() {
// 定义一个 uint64 类型的变量 v,值为 42
// uint64 是 64 位无符号整数类型,可以表示 0 到 18446744073709551615
v := uint64(42)
// 将 v 转换为十进制字符串,base = 10,表示十进制
// FormatUint 函数接收两个参数:要转换的无符号整数和进制基数
s10 := strconv.FormatUint(v, 10)
// 打印 s10 的类型和值:%T 显示类型,%v 显示值
// 这里会输出:string, 42
fmt.Printf("%T, %v\n", s10, s10)
// 将 v 转换为十六进制字符串,base = 16,表示十六进制
// 十六进制使用 0-9 和 a-f 表示 0-15的值
s16 := strconv.FormatUint(v, 16)
// 打印 s16 的类型和值:%T 显示类型,%v 显示值
// 这里会输出:string, 2a
fmt.Printf("%T, %v\n", s16, s16)
}
执行过程与结果分析
执行过程
- 变量初始化
- 创造 uint64 类型变量 v,值为 42
- uint64 是无符号64位整数,范围:0 到 18,446,744,073,709,551,615
- 十进制转换
- 调用 strconv.FormatUint(v, 10)
- 将 42 转换为十进制字符串 "42"
- 存储在变量 s10 中
- 十六进制转换
- 调用 strconv.FormatUint(v, 16)
- 将 42 转换为十六进制字符串 "2a"
- 存储在变量 s16 中
- 结果输出
- 分别打印两个转换结果的类型和值
结果分析
输出结果
string, 42
string, 2a
详细分析
- 第一行输出:string, 42
- 类型:string(字符串类型)
- 值:42(十进制表示,保持原始数值)
- 第二行输出:string, 2a
- 类型:string(字符串类型)
- 值:2a(十六进制表示)
- 转换过程:42 转换为十六进制是 2a
- 计算:42 ÷ 16 = 2 余 10,所以是 2a
关键特点
- FormatUint 函数正确处理了无符号整数,无需处理负号
- 十六进制转换使用小写字母 a-f 表示 10-15
- 两种转换都返回 string 类型,可以直接用于字符串操作
- 相比 FormatInt,FormatUint 更简洁,因为无需处理负数情况
示例2:数据库主键ID和用户ID管理
适用场景:微服务架构中的用户系统、订单系统、商品系统
// UserIDGenerator 用户ID生成器结构体
// 用于生成唯一的用户ID,结合时间戳和计数器
type UserIDGenerator struct {
counter uint64 // 计数器,用于确保ID的唯一性
}
// GenerateUserID 生成用户ID
// 使用时间戳和计数器的组合来生成唯一ID
func (g *UserIDGenerator) GenerateUserID() uint64 {
// 获取当前 Unix 时间戳(秒)
timestamp := uint64(time.Now().Unix())
// 将时间戳左移32位,然后与计数器进行或运算
// 这样时间戳占据最高32位,计数器占据低32位
userID := (timestamp << 32) | g.counter
// 计数器自增,确保下次生成的ID不同
g.counter++
return userID
}
// FormatUserID 格式化用户ID为不同进制
// 将用户ID转换为多种进制表示,便于不同场景使用
func (g *UserIDGenerator) FormatUserID(userID uint64) map[string]string {
// 创建map存储不同进制的字符串表示
formats := make(map[string]string)
// 十进制:用于数据库存储和API返回
formats["decimal"] = strconv.FormatUint(userID, 10)
// 十六进制:用于日志记录和调试(更紧凑)
formats["hex"] = strconv.FormatUint(userID, 16)
// 二进制:用于位运算分析和调试
formats["binary"] = strconv.FormatUint(userID, 2)
// 八进制:用于某些特殊编码需求
formats["octal"] = strconv.FormatUint(userID, 8)
return formats
}
func main

最低0.47元/天 解锁文章
41

被折叠的 条评论
为什么被折叠?



