strconv.atoi 转数字时会 panic,因不处理空字符串、空格、非ascii数字、unicode符号等;务必检查 error 返回值,容错需先 trim 再正则校验。

strconv.Atoi 转数字时 panic?先检查字符串是否为空或含非数字字符
直接用 strconv.Atoi 转 "123" 没问题,但遇到 ""、" 123"、"12a3" 或 "-" 就会 panic:`strconv.Atoi: parsing "": invalid syntax`。它不处理空格、前导符号异常、Unicode 数字(如全角“1”),也不接受科学计数法。
- 总是用
strconv.Atoi的返回值第二个参数(error)判断是否成功,别忽略它 - 需要容错时,先用
strings.TrimSpace去空格,再检查是否匹配正则^-?\d+$ - 想支持浮点或科学计数法?换
strconv.ParseFloat(s, 64),但注意它返回float64,不是整数 - Go 1.22+ 支持
strings.Cut快速分离符号位,但strconv本身不自动做这事
数字转字符串用 fmt.Sprintf 还是 strconv.Itoa?看场景和性能
strconv.Itoa 只支持 int,快且零分配;fmt.Sprintf("%d", n) 支持任意类型、格式化灵活,但有内存分配和解析开销。压测显示,纯转 int 时 strconv.Itoa 比 fmt.Sprintf 快 3–5 倍,分配少 90%。
- 确定是
int且只要十进制?无脑用strconv.Itoa - 要补零(如
"007")、十六进制("0xff")、或混合字符串拼接?必须用fmt.Sprintf - 转
int64别用strconv.Itoa—— 它只收int,用strconv.FormatInt(n, 10) - 大量循环内转换?避免
fmt.Sprintf,否则 GC 压力明显上升
JSON 场景下 string 和 number 自动转换的陷阱
Go 的 json.Unmarshal 默认把 JSON 数字(如 123)解到 interface{} 是 float64,不是 int 或 string。如果结构体字段声明为 string 却传入 JSON 数字,会报错:json: cannot unmarshal number into Go struct field X of type string。
- 字段明确只收数字?定义为
int、int64或float64,别用string - 字段需兼容字符串和数字(如 API 兼容旧版)?用自定义
UnmarshalJSON方法,先尝试解析为float64,再转string;或统一收json.RawMessage延后处理 - 前端传了
"123"(带引号)却被后端当字符串接收,而实际想当数字?那是协议设计问题,不是转换问题——得约定清楚字段语义
Unicode 数字、中文数字、负号长度这些边界情况
Go 字符串底层是 UTF-8,"123"(全角数字)用 strconv.Atoi 会失败,因为它是 3 个 rune,但每个 rune 的 Unicode 类别是 Nd(Number, decimal digit),不是 ASCII 数字。同样,"−123"(Unicode 减号 U+2212)≠ ASCII "-"(U+002D)。
- 需要支持 Unicode 数字?别用
strconv,改用golang.org/x/text/unicode/norm先标准化,或手动映射(不推荐) - 判断字符串是否“看起来像数字”?用
unicode.IsDigit遍历每个rune,但注意它包含罗马数字、上标数字等,不等于“可转为 int” - 计算字符串数字长度?别用
len(s),那是字节数;用utf8.RuneCountInString(s)才是真实字符数
字符串和数字互转看着简单,真正卡住人的从来不是语法,而是那些没报错但结果不对的情况:空格、编码、JSON 类型推断、Unicode 归一化。多打两行 error 判断,比事后查日志快得多。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











