字符串转数字必须用strconv.Parse系列并检查错误,数字转字符串优先用strconv.Itoa或strconv.Format;ParseInt比Atoi更安全可控,因Atoi隐式依赖平台int大小、不支持自动进制识别且超范围会静默截断。

直接说结论:字符串转数字必须用 strconv.Parse* 系列并检查错误,别图省事写 strconv.Atoi 就完事;数字转字符串优先用 strconv.Itoa 或 strconv.Format*,永远比 fmt.Sprintf 快且安全。
ParseInt 和 Atoi 到底该选哪个?
strconv.Atoi 只是 strconv.ParseInt(s, 10, 0) 的封装,它隐式依赖平台 int 大小(32 位系统返回 int32,64 位返回 int64),但项目里常需要明确精度或进制:
- 输入是
"0xFF"?Atoi直接报invalid syntax,得换strconv.ParseInt("0xFF", 0, 64)(base=0自动识别前缀) - 要转成
int32但值超范围?Atoi先返回int64再强转会静默截断,而ParseInt(s, 10, 32)明确返回ERANGE - 字符串带空格如
" 42 "?Atoi失败,得先strings.TrimSpace,ParseInt同样不跳过空白——这点没区别,都得预处理
ParseFloat 的第二个参数不是“保留几位小数”
strconv.ParseFloat(s, bitSize) 的 bitSize 控制返回值类型:传 32 得 float32,传 64 得 float64。它不控制格式精度,也不做四舍五入:
-
strconv.ParseFloat("1.23456789", 32)返回的是截断后的float32值(约1.2345679),不是“保留 32 位有效数字” - 想输出固定小数位数(比如日志里显示两位),那是
strconv.FormatFloat的事,不是ParseFloat的职责 - 科学计数法如
"1e-5"能正常解析;但"1.2e"会报invalid syntax,因为指数缺数字
错误处理不能只写 if err != nil
strconv 的错误是 *strconv.NumError,它带三个关键字段:Func(哪个函数出的错)、Num(原始字符串)、Err(底层错误)。只打印 err.Error() 会丢失上下文:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 用户提交
"abc"导致失败,你得知道是ParseInt还是ParseFloat拒绝的——查err.(*strconv.NumError).Func - 日志里想提示“无法解析数字:
abc”,就用err.(*strconv.NumError).Num提取原始输入 - 在 HTTP API 中返回友好错误时,别直接透出
strconv.ParseInt: parsing "abc": invalid syntax,那属于实现细节
高频调用场景下的性能注意点
如果在循环里每秒解析成千上万个数字(比如解析日志行、协议帧),strconv.ParseInt(string(b[:n]), 10, 64) 这种写法会反复分配字符串,拖慢性能:
- 输入是
[]byte?优先用strconv.Read*Int配合bytes.Reader流式读,避免拷贝 - 格式高度可控(如纯 ASCII 数字),可手写简易解析(跳过空格 + 逐字节累加),但仅限内部可信数据
-
strconv.Itoa比fmt.Sprintf("%d", n)快 3–5 倍,这点很稳;但反向(字符串→整数)没有无分配替代方案,只能接受它
真正容易被忽略的,是错误类型的断言和原始输入提取——很多团队线上出了问题才意识到,日志里只有模糊的 “invalid syntax”,却不知道具体哪条数据、哪个字段、什么内容触发的。这比选错函数更难排查。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










