Go 入门(10):字符串操作——strings 标准库与 strconv 转换
更新时间:2026-09-01。本文是
languages/go/beginner/入门层第 10 篇,接 包与模块。Go 字符串天生支持 UTF-8,不可变,标准库strings包提供了所有常用操作,strconv负责字符串和数字互转。
本文要回答的问题
- Go 字符串是 UTF-8,字节和字符是什么关系?len() 为什么不一定是字符数?
- strings 包常用的操作有哪些?拼接、切割、替换、查找怎么写?
- strconv 怎么转数字?怎么处理错误?
- 拼接字符串为什么有时候效率低?用什么拼接更快?
一、Go 字符串回顾
Go 字符串是不可变的 UTF-8 字节序列:
go
s := "性能剖析"
fmt.Println(len(s)) // 12,len 返回字节数,每个中文 UTF-8 占 3 字节
fmt.Println([]rune(s)) // [24615 35299 20214 26524],4 个字符
fmt.Println(len([]rune(s))) // 4,字符数是 4记住:
len(s)→ 字节数len([]rune(s))→ 字符数(Unicode 码点数)for range s→ 按 Unicode 字符迭代
二、strings 包常用操作
1. 查找判断
go
strings.Contains(s, "sub") // 是否包含子串
strings.HasPrefix(s, "pre") // 是否以前缀开头
strings.HasSuffix(s, "fix") // 是否以后缀结尾
strings.Index(s, "sub") // 第一次出现的位置,-1 表示不包含2. 切割拼接
go
// 按分隔符切割
parts := strings.Split("a,b,c", ",") // ["a" "b" "c"]
// 按空白字符切割
fields := strings.Fields("a b c") // ["a" "b" "c"]
// 拼接
s := strings.Join([]string{"a", "b"}, ",") // "a,b"3. 替换
go
// 替换所有匹配
newS := strings.ReplaceAll("aaa", "a", "b") // "bbb"
// 替换 n 次,n=-1 替换所有
newS = strings.Replace("aaa", "a", "b", 2) // "bba"4. 修剪
go
s = strings.TrimSpace(" hello world \n") // "hello world",去掉前后空白
s = strings.Trim("###hello###", "#") // "hello",去掉前后指定字符5. 大小写转换
go
strings.ToLower("HELLO") // "hello"
strings.ToUpper("hello") // "HELLO"三、字符串拼接:+ vs strings.Builder vs bytes.Buffer
Go 字符串不可变,所以每次 s += "abc" 都会分配新内存,拷贝旧内容过去。小字符串没事,循环拼很多就慢。
循环拼接推荐用 strings.Builder:
go
var builder strings.Builder
for i := 0; i < 1000; i++ {
builder.WriteString("a")
}
s := builder.String()性能对比:
+→ 适合少量拼接,语法简洁strings.Builder→ 适合大量循环拼接,预分配内存,少拷贝bytes.Buffer→ 也能用,但strings.Builder更专门
四、strconv:字符串和数字互转
字符串转数字
go
// 字符串转 int
i, err := strconv.Atoi("123") // i=123, err=nil
i, err := strconv.Atoi("abc") // err != nil
// 字符串转 int64 或其他进制
i64, err := strconv.ParseInt("123", 10, 64) // 10进制,64位
u64, err := strconv.ParseUint("123", 16, 64) // 16进制
// 字符串转 float64
f, err := strconv.ParseFloat("3.14", 64)数字转字符串
go
s := strconv.Itoa(123) // "123"
s := strconv.FormatInt(123, 10) // 转成指定进制字符串
s := strconv.FormatFloat(3.14, 'f', 2, 64) // "3.14"转布尔
go
b, err := strconv.ParseBool("true") // true五、常见坑对照
| 坑 | 现象 | 对策 |
|---|---|---|
| len(s) 以为是字符数 | 中文 len 结果比字符数大 | 转 []rune 再算 len |
| 循环用 += 拼大量字符串 | 内存分配多,慢 | 用 strings.Builder |
[]byte(s) 转换后修改 | 改 []byte 不影响原字符串,因为是拷贝 | 要改就先转 []byte,改完再转 string |
| strconv 不检查错误 | 转换失败得到零值,继续跑 | 一定要检查 err |
| 正则表达式重复编译 | 循环里每次编译,慢 | 用 regexp.Compile 一次编译完放全局 |
相关与延伸
下一篇:正则表达式——regexp 包用法;字符串的 UTF-8 编码和 rune 类型,在 语法基础 提到过;Go 字符串内存结构,进阶层讲内存布局。
一句话总结
Go 字符串:不可变 UTF-8 字节序列,len 是字节数,转 []rune 才能得到 Unicode 字符数;strings 包提供 Contains、Split、Join、Replace、Trim 等常用操作;strconv 做字符串和数字互转,转换必须检查错误;循环拼接大量字符串用 strings.Builder,别用 +=。