strconv.ParseInt 不会 panic,而是返回非 nil error;其校验分两步:先解析为 uint64,再检查是否在目标 intN 范围内,bitSize 决定上下限而非截断,忽略 err 会导致静默错误。

strconv.ParseInt 为什么会在 int64 范围外直接 panic?
它根本不会 panic —— strconv.ParseInt 在输入超出目标类型范围时,返回的是一个非 nil 的 error,而不是 panic。常见误解是看到 strconv.ParseInt("9223372036854775808", 10, 64)(比 math.MaxInt64 大 1)报错就以为“越界崩溃”,其实只是 err != nil。它的边界校验逻辑非常明确:先按字符串解析出完整整数值(内部用 uint64 存),再判断是否能无损映射到目标有符号整型。
ParseInt 的位宽参数(bitSize)如何影响校验逻辑?
bitSize 决定了最终结果的存储类型和校验上限,不是“只取低 N 位”。比如 strconv.ParseInt("128", 10, 8) 返回 0 和 strconv.ErrRange,因为 128 超出 int8 的 [-128, 127] 范围;而 strconv.ParseInt("-129", 10, 8) 同样失败。校验分两步:
① 解析为无符号大整数(支持最多 64 位)
② 检查该值能否表示为指定 bitSize 的有符号整数 —— 即是否满足 min ≤ value ≤ max,其中 min/max 由 int8/int16/int32/int64 的定义决定。
常见误用:把 ParseInt 当作“安全截断”工具
有人试图用 strconv.ParseInt(s, 10, 32) 来“自动截断超长数字”,这是错的。它不会返回 value & 0xFFFFFFFF,而是直接报 strconv.ErrRange。如果你需要截断语义(比如协议兼容),必须自己做位运算或用 int32(unsafeConv) 配合 math/bits 判断溢出,但要注意这绕过了 Go 类型安全。
- 错误写法:
n, _ := strconv.ParseInt("2147483648", 10, 32)→ 实际 n=0, err!=nil,忽略 err 会导致静默错误 - 正确做法:显式检查
err == strconv.ErrRange,再决定是报错、降级、还是手动处理 - 注意:即使字符串合法(如 "0"),bitSize=0 或 bitSize>64 会触发
strconv.NumError,且err.(*strconv.NumError).Err == strconv.ErrSyntax
性能与边界校验开销是否可忽略?
ParseInt 的边界校验本身成本极低 —— 它本质是两次比较(vs min/max 常量),远低于字符串遍历和十进制转换。真正耗时的是大数字解析(比如上万位字符串),此时内部会用到 uint64 累加并频繁检查溢出,但只要没触发 ErrRange,这部分仍是 O(n)。不过要注意:
• 小数字(典型场景):校验几乎无额外开销
• 极长数字(罕见):解析阶段就可能因多次进位计算变慢,但边界判断仍只在最后执行一次
• 如果你已知输入一定在 int32 范围内,用 strconv.ParseInt(s, 10, 32) 比先 ParseInt(..., 64) 再 int32() 更安全,避免中间 int64 溢出风险
立即学习“go语言免费学习笔记(深入)”;
边界校验逻辑藏在 runtime 包的parseUint 和 parseDecimal 里,但用户只需记住:它不 panic、不截断、不妥协 —— 错就是错,得自己 handle。


















