strings.Contains 对空字符串恒返回 true,需先校验 len(substr) > 0;区分 strings.Split(按指定分隔符,保留空字段)与 strings.Fields(按 Unicode 空白,自动过滤);多子串替换优先用 strings.Replacer。

strings.Contains 判断子串存在但要注意空字符串陷阱
这个函数返回 bool,用于检查源字符串是否包含指定子串。它看似简单,但遇到 ""(空字符串)时行为容易误判:strings.Contains("hello", "") 恒为 true,因为按定义空字符串是任意字符串的子串。实际业务中若逻辑依赖“非空子串匹配”,必须先做 len(substr) > 0 校验。
常见错误场景:用户输入搜索关键词为空时,直接传入 strings.Contains(text, userInput),结果所有文本都被“命中”。
- 只适用于 ASCII 或 UTF-8 编码的原始字节匹配,不支持正则或忽略大小写
- 若需忽略大小写,应先用
strings.ToLower统一转换(注意性能开销) - 底层是朴素字符串匹配,长度超过几千字符时建议改用
strings.Index+ 循环判断,避免重复扫描
strings.Split 和 strings.Fields 处理分隔符要区分“空白 vs 明确分隔符”
strings.Split 按给定分隔符切分,保留空字段;strings.Fields 按 Unicode 空白字符(空格、制表符、换行等)分割,自动跳过首尾及连续空白,并丢弃空结果。二者语义完全不同,选错会导致数据丢失或格式错乱。
例如解析 CSV 行时用 strings.Fields 会把 "a, b, c" 错切成 ["a,", "b,", "c"];而用 strings.Split("a, b, c", ",") 得到 ["a", " b", " c"],需额外 strings.TrimSpace。
立即学习“go语言免费学习笔记(深入)”;
-
strings.Split(s, "")会将字符串拆成单字符[]string,但效率低,高频场景建议用[]rune(s) - 分隔符为多字符(如
"::")时,strings.Split正常工作;但strings.FieldsFunc更适合按复杂规则(如“非字母数字即分隔”)切分 - 大字符串反复
Split后取部分字段?考虑用strings.Index+strings.IndexByte手动定位,减少内存分配
strings.ReplaceAll 和 strings.Replacer 在批量替换时性能差异明显
strings.ReplaceAll 是单次替换所有匹配项,简洁直接;但若需同时替换多个不同子串(如 HTML 转义:&→&、→),多次调用 ReplaceAll 会产生中间字符串,GC 压力大。
此时应改用 strings.NewReplacer 构建复用对象:replacer := strings.NewReplacer("&", "&", "", ">"),再调用 replacer.Replace(s)。它内部预编译映射表,一次扫描完成全部替换,实测在千字以上文本中快 3–5 倍。
-
strings.Replace(带 count 参数)可用于限制替换次数,比如只替换前两个"foo" -
strings.Replacer不支持正则,也不处理重叠匹配(如替换"aaa"→"b",输入"aaaa"只变两次,得"bb") - 若替换规则动态生成,注意
strings.NewReplacer参数必须成对,奇数个参数 panic
strings.Builder 是拼接大量字符串唯一推荐的高效方式
用 + 或 fmt.Sprintf 拼接几十次以上字符串,会因不可变性导致频繁内存分配和拷贝。正确做法是初始化 strings.Builder,反复调用 WriteString 或 WriteRune,最后 builder.String() 一次性产出结果。
关键点:Builder 内部使用 slice,Grow 可预估容量(如已知最终约 10KB,调用 b.Grow(10240)),避免多次扩容;且 builder.Reset() 可复用实例,比新建更省。
- 不要对 Builder 做并发写入——它不是线程安全的
- 若拼接内容含格式化(如数字转字符串),优先用
builder.WriteString(strconv.Itoa(n))而非fmt.Fprintf(&b, "%d", n),前者无反射开销 - Builder 的零值可用,无需显式
new或&strings.Builder{}
package main
import "strings"
func main() {
var b strings.Builder
b.Grow(128)
b.WriteString("Hello")
b.WriteByte(' ')
b.WriteString("World")
result := b.String() // "Hello World"
}
Go 的 strings 包多数函数都是纯函数、无副作用,但真正影响性能的往往是内存分配模式和 Unicode 处理边界——比如 strings.Title 已被标记为 deprecated,因其对非 ASCII 字符处理不符合预期,这种细节很容易被忽略。










