应先预处理再用 strconv.parseuint 判断:trim 空格、拒绝空串/负号/前导零(除单个"0"),最后用 parseuint(s, 10, 64) 校验是否为可安全转为 uint64 的非负整数。

用 strconv.Atoi 判断整数字符串,但会误判负号和空字符串
直接调用 strconv.Atoi 是最常用的做法,但它只认「合法十进制整数」:允许开头带 - 或 +,但不允许小数点、空格、前导零(如 "0123" 在 Go 1.20+ 默认允许,但语义上仍是合法整数)。
常见陷阱:
-
"-42"→ 成功,返回err == nil,但你可能只想接受正整数 -
""或" "→ 失败,err != nil,但错误类型是strconv.ErrSyntax,不是空指针 -
"00"→ 成功,但若业务要求「无前导零」,需额外校验len(str) == 1 || str[0] != '0'
用 regexp.MatchString 校验纯数字字符,但不处理语义边界
正则 "^[0-9]+$" 看似干净,实际只做字符集检查,完全不管数值合法性:
-
"000"、"0"都匹配成功,但它们是否算“有效数字”取决于业务(比如 ID 不允许全零) -
"123\n"或"123 "→ 不匹配(因为^和$锚定首尾),但若输入含不可见空白,得先strings.TrimSpace - 无法区分
"0"和"00",也无法拒绝超长数字(如 1000 位字符串),而strconv会在解析时自然截断或报错
用 unicode.IsDigit 逐字符判断,适合严格 ASCII 场景
如果明确只要 0–9(不接受罗马数字、全角数字、分数等),unicode.IsDigit 比 unicode.IsNumber 更精准:
-
unicode.IsNumber('Ⅶ')→true(罗马数字七),但多数 API 只要阿拉伯数字 -
unicode.IsDigit('7')→true;unicode.IsDigit('Ⅶ')→false - 注意:必须遍历每个
rune,不能用byte索引,否则中文或 emoji 下标越界 - 示例:
func isAllDigits(s string) bool { for _, r := range s { if !unicode.IsDigit(r) { return false } } return len(s) > 0 // 排除空字符串 }
真正要校验「可安全转为 int64 的非负整数」,得组合预处理 + strconv.ParseUint
很多场景其实不是问「是不是数字字符」,而是「能不能当 ID、版本号、端口号用」——即:非负、无符号、长度合理、无前导零(可选)。
- 先
strings.TrimSpace(s)去首尾空格 - 拒绝空字符串:
if len(s) == 0 { return false } - 拒绝负号:
if s[0] == '-' || s[0] == '+' { return false } - 拒绝前导零(除非单个
"0"):if len(s) > 1 && s[0] == '0' { return false } - 最后用
_, err := strconv.ParseUint(s, 10, 64),它比Atoi更明确表示「无符号」,且对溢出返回strconv.ErrRange
这一步才是生产环境里最接近「用户真实意图」的判断:不是字符游戏,而是数值可用性。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











