strconv.atoi 本身不 panic,panic 源于忽略其返回的 error 后用零值参与计算;必须用 i, err := strconv.atoi(s) 并检查 err;它不处理空格或空字符串,仅支持十进制。

strconv.Atoi 转整数时 panic 的真实原因
不是 strconv.Atoi 本身会 panic,而是它返回的 error 被你忽略后,用零值参与后续计算导致崩溃。比如把 "abc" 传进去,得到 0, fmt.Errorf("strconv.Atoi: parsing \"abc\": invalid syntax"),如果你直接拿这个 0 当有效数字用,逻辑就错了。
- 必须检查返回的
error:永远别写i := strconv.Atoi(s)这种单值赋值 - 正确写法是
i, err := strconv.Atoi(s); if err != nil { /* 处理错误 */ } - 注意:空字符串
""、带空格的字符串如" 123"(没 trim)都会失败,strconv.Atoi不做任何格式预处理 - 性能上它比
fmt.Sscanf快不少,但只支持十进制,八进制/十六进制得用strconv.ParseInt(s, base, bitSize)
ParseFloat 解析小数时精度丢失不是 bug
strconv.ParseFloat 按 IEEE-754 双精度规则转换,和 Go 的 float64 类型行为完全一致。你看到 "0.1" → 0.10000000000000000555,不是函数问题,是二进制浮点数根本存不了精确的十进制小数。
- 如果需要精确小数运算(比如金额),别用
float64,改用整数单位(分)或第三方库如shopspring/decimal -
ParseFloat(s, 64)和ParseFloat(s, 32)返回类型不同,后者是float32,精度更低,别混用 - 科学计数法字符串如
"1.23e-4"是合法输入,但"1.23E-4"(大写 E)也支持,不用额外处理
itoa 和 FormatInt:选哪个取决于你是否控制进制
strconv.Itoa 是 FormatInt(i, 10) 的快捷写法,仅限十进制。一旦你需要八进制、十六进制、甚至二进制,就必须切到 FormatInt 或 FormatUint。
-
strconv.Itoa(255)→"255";strconv.FormatInt(255, 16)→"ff"(小写) - 十六进制想转大写?用
strings.ToUpper(strconv.FormatInt(255, 16)),strconv本身不提供大小写开关 - 注意负数:
FormatInt(-10, 10)返回"-10",但FormatUint只接受无符号类型,传负数会编译报错 - 性能敏感场景下,
Itoa略快于FormatInt(x, 10),但差异微乎其微,可读性优先
字符串转布尔值别只认 "true"/"false"
strconv.ParseBool 实际支持更多字符串:"1"、"t"、"T"、"TRUE"、"true" 都算 true;"0"、"f"、"F"、"FALSE"、"false" 算 false。这点常被忽略,导致配置文件里写 enabled: 1 却解析失败。
立即学习“go语言免费学习笔记(深入)”;
- 它不接受空格包裹的字符串,
" true "会报错,必须提前strings.TrimSpace - 注意大小写:虽然
"True"合法,但"TRUELY"不合法,只匹配完整单词或单字符 - API 接收 JSON 时,布尔字段本该是
true/false布尔字面量,若后端误当字符串接收再用ParseBool,容易掩盖类型错误
事情说清了就结束。真正麻烦的从来不是怎么转,而是谁负责校验输入、谁决定错误策略、以及下游是否真的能处理你塞过去的那个 0 或 false。










