strconv.atoi 不会 panic,而是返回 (int, error);它在解析失败时返回 0 和具体错误,需显式检查 err != nil,否则可能导致静默错误。

strconv.Atoi 会 panic 吗?不会,但会返回 error
strconv.Atoi 是最常用的字符串转整型函数,但它**从不 panic**,而是返回 (int, error)。很多人误以为它像 Python 的 int() 那样直接报错崩溃,其实 Go 把错误交给你自己判断——这既是安全设计,也是容易漏掉 err != nil 检查的根源。
- 输入
"123"→ 返回123, nil - 输入
"abc"→ 返回0, strconv.ParseInt: parsing "abc": invalid syntax - 输入
"12345678901234567890"(超出 int 范围)→ 返回0, strconv.ParseInt: parsing "...": value out of range
为什么用 strconv.ParseInt 而不是 Atoi?精度和位宽控制
strconv.Atoi 本质是 strconv.ParseInt(s, 10, 0) 的封装,其中 0 表示“用当前平台的 int 位宽”(通常是 64 位)。但生产环境里,你往往需要明确指定类型和范围,比如存进数据库字段是 int32,或解析 HTTP 查询参数时防溢出。
- 转成
int32:用strconv.ParseInt(s, 10, 32),返回int64,需手动转int32(注意溢出检查) - 转成无符号:用
strconv.ParseUint(s, 10, 64),别错用ParseInt解析负数字符串 - 进制不一定是 10:URL 中的十六进制 ID(如
"ff")得用strconv.ParseInt("ff", 16, 64)
常见错误:忽略 err 或直接强制转换导致静默 0 值
最典型的问题是写成 n := strconv.Atoi(s),丢掉 error,结果 s 是空字符串或非数字时,n 变成 0——逻辑继续执行,但数据已错,且难以排查。
- 错误写法:
n, _ := strconv.Atoi(s)(下划线吞掉 error) - 危险写法:
n := int(strconv.ParseInt(s, 10, 64))(没检查 error 就强转) - 正确姿势:必须显式判断
if err != nil,并决定是返回错误、默认值,还是记录日志 - 注意:
ParseInt返回的是int64,直接赋给int32变量会编译报错,需加类型断言或转换
实战建议:封装一个带默认值和日志的 safeAtoi
项目里反复写 if err != nil 很啰嗦,可以封装一层,但别过度抽象——保持错误可追踪、行为可预期。
func safeAtoi(s string, def int) (int, error) {
n, err := strconv.Atoi(s)
if err != nil {
log.Printf("safeAtoi failed on %q: %v", s, err)
return def, err
}
return n, nil
}
- 不要去掉 error 返回:即使有默认值,调用方仍应知道转换失败过
- 避免在日志里打印敏感值(如密码类参数),用
%q包裹字符串更安全 - 如果默认值本身有意义(如分页 offset 默认 0),就保留;若 0 是非法值,不如让 error 透出
真正麻烦的不是转换本身,而是你没想清楚这个字符串本该来自哪里、是否可信、边界在哪——比如用户输入的 ID,应该先校验正则 ^[0-9]+$ 再 parse,而不是靠 ParseInt 的 error 当兜底。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











