Go语言字符串转数值必须用strconv包,如Atoi、ParseInt、ParseFloat并严格检查error;数值转字符串优先用Itoa或Format*系列,避免fmt.Sprintf开销。

string 转数值:用 strconv 包,别直接类型断言
Go 里 string 和数值类型(如 int、float64)之间不能直接赋值或强制转换。常见错误是写 int("123") 或 string(42) —— 这会编译失败,因为 Go 不支持隐式类型转换。
正确做法是用 strconv 包的解析函数:
-
strconv.Atoi("123")→ 返回(int, error),适合十进制整数 -
strconv.ParseInt("123", 10, 64)→ 更精确控制进制和位宽,返回(int64, error) -
strconv.ParseFloat("3.14", 64)→ 解析浮点数,注意精度对应float64或float32
必须检查 error:空字符串、含非数字字符(如 "12a")、溢出(如 "999999999999999999999")都会返回非 nil 错误。
数值转 string:优先用 strconv.Format*,少用 fmt.Sprintf
fmt.Sprintf 能用,但它是通用格式化函数,带反射和格式解析开销;对简单转换来说,strconv 的 Format* 系列更轻量、更明确。
立即学习“go语言免费学习笔记(深入)”;
-
strconv.Itoa(42)→ 最快的int转string(等价于FormatInt(int64(42), 10)) -
strconv.FormatInt(int64(42), 16)→ 转十六进制字符串(结果为"2a") -
strconv.FormatFloat(3.1415, 'g', -1, 64)→ 第三个参数是精度(-1 表示最短有效表示),'g' 是常用格式
注意:FormatFloat 的精度参数不是小数位数,而是有效数字位数;要固定小数位,得用 fmt.Sprintf("%.2f", x),但此时已接受其开销。
byte slice 和 string 互转:零拷贝仅限 UTF-8 安全场景
常见误区是认为 string(b) 和 []byte(s) 是“无成本转换”。实际上,它们在底层会复制底层数组数据(Go 1.22 之前),除非编译器能证明安全并优化掉。
- 如果
s是字面量或只读且生命周期可控,[]byte(s)可能被优化为零拷贝(但不保证) - 反之,
string(b)总是安全的,但若b后续会被修改,而你又把生成的string长期持有,就可能引发意外行为(因底层数据被改) - 真正需要零拷贝时,应使用
unsafe.String/unsafe.Slice(Go 1.20+),但需确保内存生命周期和 UTF-8 合法性
日常开发中,优先走标准转换;只有 profiling 显示这部分成为瓶颈,再考虑 unsafe 方案。
Unicode 和 rune:别把 string 当字节数组遍历
Go 的 string 是 UTF-8 编码的字节序列,一个中文字符占 3 字节,len(s) 返回的是字节数,不是字符数。直接用 for i := range s 得到的是 rune(Unicode 码点)位置,而 s[i] 拿到的是字节,不是字符。
- 要按字符遍历:用
for _, r := range s,r是rune类型 - 要转成
[]rune:用[]rune(s),这会解码 UTF-8 并分配新切片 - 拼接含 emoji 或中文的字符串时,用
strings.Builder或fmt.Sprintf更安全,避免手动索引出错
混淆字节和字符是调试中最难发现的 bug 来源之一,尤其在处理用户输入或国际化文本时。


















