go字符串操作核心是查、改、拼三类:查用contains/index/hasprefix等;改用replaceall或replace;拼接少用+、多用strings.builder;unicode操作需转[]rune。

Go 字符串操作不是“学一堆函数”,而是搞清三件事:怎么查、怎么改、怎么拼——其余全是这三类的变体或优化。
怎么判断子串存在或位置?用 strings.Contains、strings.Index 而不是自己遍历
日常最常卡住的是:想确认日志里有没有“timeout”,却写了个 for 循环加 byte 比较。没必要。
-
strings.Contains返回bool,语义清晰,底层是 memchr 优化过的,比手写快且安全 - 需要知道“在哪”时,用
strings.Index(第一次)或strings.LastIndex(最后一次),找不到返回-1,别忘了判空 - 前缀/后缀检查优先用
strings.HasPrefix和strings.HasSuffix,它们比strings.Index == 0更直观、也更高效 - 别用
strings.Index去找中文字符位置再切片——它返回的是字节偏移,不是字符索引;要按“第几个字”切,得转[]rune
怎么替换内容?认准 strings.ReplaceAll,老版本才碰 strings.Replace
Go 1.12+ 直接上 strings.ReplaceAll,语义干净,不用纠结参数 n。
-
strings.ReplaceAll(s, "old", "new")替换全部,无脑可靠 - 只换第一个?用
strings.Replace(s, "old", "new", 1),n=1明确表达意图 - 想替换所有但又怕误伤(比如只换单词边界)?
strings.ReplaceAll不支持正则,此时该上regexp.ReplaceAllString,别硬套字符串函数 - 敏感词过滤场景下,多次调用
ReplaceAll效率低,应预编译正则或用 AC 自动机——但那是另一层问题,别在字符串基础操作里埋坑
怎么拼接字符串?看规模:少用 +,多用 strings.Builder,别用 fmt.Sprintf 当胶水
拼接不是语法问题,是内存和性能问题。每次 + 都新建字符串,循环 1000 次 = 1000 次分配 + 拷贝。
- 拼 2–5 个已知字符串?
a + b + c完全 OK,可读性高,编译器还能优化 - 循环内拼接、日志组装、HTML 构建?必须用
strings.Builder:b.WriteString(s)零拷贝追加,b.String()直接返回结果 - 初始化时能预估长度就调
b.Grow(2048),减少扩容次数 -
fmt.Sprintf("%s%s", a, b)是反模式——它要解析格式串、做反射、处理类型,纯拼接比+还慢;只有带格式需求(如%06d、%q)才用它
怎么处理中文、emoji 等 Unicode 字符?别信 len(),该转 []rune 就转
len("你好") == 6 是对的,但它不是“字符数”。很多 bug 都出在把字节当字符用。
- 截断显示、计算昵称长度限制、分页取前 10 个字?必须用
utf8.RuneCountInString(s)或先转[]rune(s)再len() - 想取第 3 个汉字?
[]rune(s)[2]可行,但别在热循环里反复转——缓存[]rune或改用for range遍历 for i := 0; i 会把中文拆成乱码字节,永远别这么干;正确方式是 <code>for _, r := range s { fmt.Printf("%c", r) }- 拼接本身不关心 Unicode——
+和Builder都按 UTF-8 字节流处理,结果一定正确;出错只发生在“按位置操作”时
真正容易被忽略的,是把 len() 当字符计数器用,以及在循环里无意识地把 strings.ReplaceAll 当正则使——它不识别边界,"go" 会把 "golang" 也替掉。遇到这种需求,就得跳出 strings 包了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











