strconv 是 Go 中字符串与数字互转的唯一标准库方案,专为安全、明确、可控设计;必须用 strconv.Atoi 处理外部输入,因其错误类型明确,而 fmt.Sscanf 易静默截断;ParseFloat 的 bitSize 参数指位宽非小数位数,应优先用 64;ParseBool 仅认 "true"/"false"/"1"/"0";高频拼接应避免重复调用 strconv.Itoa,改用 AppendInt 或 fmt.Sprintf;所有解析函数不自动 trim 空格。

Go 语言里 strconv 是做基础字符串与数字互转的唯一标准库方案,没有替代品,也不该用 fmt.Sscanf 或反射凑合——它专为安全、明确、可控而设计。
什么时候必须用 strconv.Atoi 而不是 fmt.Sscanf
当你要把用户输入、配置文件字段、HTTP 查询参数这类外部字符串转成整数时,strconv.Atoi 是首选。它返回 (int, error),错误类型明确(比如 "invalid syntax" 或 "value out of range"),便于区分是格式错还是溢出。
而 fmt.Sscanf 不校验进制、不区分空格和非法字符、错误信息模糊,还可能静默截断——比如 fmt.Sscanf("123abc", "%d", &i) 居然成功赋值 i=123,这在参数校验场景下是灾难。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 始终检查
error:哪怕你“确定”输入合法,也要写if err != nil { return err } - 需要指定进制(如十六进制)或位宽(如
int64)时,改用strconv.ParseInt(s, 16, 64) - 别用
strconv.Atoi解析带符号前缀的字符串(如"+123")——它支持,但很多人不知道;真正不支持的是带空格或单位(如"123px")
strconv.ParseFloat 的精度陷阱和位宽选择
strconv.ParseFloat(s, bitSize) 第二个参数不是小数位数,而是目标浮点类型的位宽:传 64 得 float64,传 32 得 float32。传错会导致意外精度丢失或 panic(如果字符串精度远超 float32 表达范围)。
常见错误现象:strconv.ParseFloat("9999999999.123456789", 32) 返回的值可能已经是 1e10,因为 float32 有效位只有约 7 位十进制数字。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 除非内存敏感且数值范围小(如传感器原始读数),否则统一用
64 - 不要指望它能“四舍五入到小数点后两位”——那是格式化(
fmt.Sprintf("%.2f", x))的事,ParseFloat只负责忠实解析 - 遇到科学计数法字符串(如
"1.23e-4")完全没问题,strconv原生支持
字符串 ↔ 布尔值:为什么 strconv.ParseBool 只认四个字符串
strconv.ParseBool 只接受 "true"、"false"、"1"、"0"(大小写不敏感)。它**不认** "yes"、"on"、"enabled",也不认 JSON 风格的 "null" 或空字符串。
这是刻意设计:避免业务语义污染底层转换逻辑。如果你的 API 接收 status=enabled,那就该在 handler 层做映射,而不是改用非标解析函数。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- HTTP 查询参数或表单提交中布尔字段,优先约定用
1/0或true/false,省去中间映射 - 若必须兼容多形态,自己写一个薄封装,例如:
func ParseBoolExt(s string) (bool, error) { ... },内部用strings.EqualFold判断 - 注意:空字符串
""会返回false, fmt.Errorf("parsing \"\": invalid syntax"),不是false, nil
性能关键:避免重复调用 strconv.Itoa 拼接大量数字
strconv.Itoa 是 strconv.FormatInt(i, 10) 的快捷方式,每次调用都分配新字符串。在高频日志、序列化循环中反复用它拼接(比如 "id:" + strconv.Itoa(id) + ",name:" + name),会显著增加 GC 压力。
更优解是预分配或复用缓冲区:
- 简单拼接 3–4 个字段:用
fmt.Sprintf(底层有 fast-path 优化) - 高吞吐场景(如 metrics 打点):用
strconv.AppendInt直接操作[]byte,例如:b := []byte("id:"); b = strconv.AppendInt(b, int64(id), 10); b = append(b, ',') - 千万别为了“看起来快”而手写除法转字符串——
strconv内部用了无分支查表和 uint64 优化,比你能写的任何手动实现都稳
最易被忽略的一点:所有 strconv 解析函数对前导/后缀空白符零容忍。字符串带空格?先 strings.TrimSpace,别指望它自动 trim——这不是 bug,是设计契约。










