strings.contains 是最直接的子串判断方式,时间复杂度 o(n),大小写敏感且不支持通配符;需忽略大小写时应统一转小写再查,避免正则或 index 误用。

用 strings.Contains 是最直接的方式
Go 标准库的 strings.Contains 就是为此设计的,时间复杂度 O(n),底层用的是朴素匹配(对绝大多数场景已足够快)。它不区分大小写,也不支持通配符或正则——纯看子串是否连续出现。
常见错误是误以为它支持模糊匹配或忽略空格,比如传入 "hello" 去查 "HELLO" 会返回 false。
示例:
import "strings" s := "hello world" has := strings.Contains(s, "world") // true has = strings.Contains(s, "WORLD") // false,大小写敏感
需要忽略大小写时,先转再查
strings.Contains 本身不提供 ignore-case 参数,所以得手动统一大小写。推荐用 strings.ToLower(不是 strings.ToUpper,因为某些 Unicode 字符在大写转换时行为更复杂)。
注意:如果字符串含非 ASCII 字符(如中文、德语变音符号),strings.ToLower 仍安全,但别用 bytes.EqualFold 直接比字节——它只适合两个字符串都已知且要判等,不适合“子串存在性”判断。
实操建议:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 只对被搜索字符串和子串都调用
strings.ToLower,再传给strings.Contains - 如果高频调用,考虑提前缓存小写版本,避免重复分配
- 别用
strings.Index+ 判 >= 0 替代——语义不清,且多一次计算
性能敏感场景下避免重复分配
当你要在循环里反复判断同一字符串是否含多个不同子串时,每次调用 strings.ToLower(s) 都会新建字符串,造成 GC 压力。
更优做法是预先转好小写副本,然后复用:
s := "Hello World"
sLower := strings.ToLower(s)
for _, sub := range []string{"hello", "world", "GO"} {
if strings.Contains(sLower, strings.ToLower(sub)) {
// ...
}
}
另外,如果子串长度固定且极短(如 1–2 字节),可考虑用 strings.IndexByte 或遍历字节切片,但仅限极端优化需求——标准库函数已足够快,过早优化反而增加维护成本。
别用正则表达式做简单子串判断
有人看到“匹配”就直奔 regexp.MatchString,但正则引擎启动开销大,编译模式还有缓存成本。对纯子串查找,它比 strings.Contains 慢 5–10 倍以上,且易引入意外行为(比如 . 匹配任意字符)。
除非你真需要:
– 子串带通配逻辑(如 "a?c")
– 跨行匹配或边界控制(\bword\b)
– 多模式批量匹配(这时该用 regexp.MustCompile 预编译)
否则一律用 strings.Contains。
一个容易被忽略的点:Go 的字符串是 UTF-8 编码,strings.Contains 按字节匹配,但 Go 运行时保证了对合法 UTF-8 字符串的操作是安全的——你不需要手动拆 rune,除非你在处理截断或计数逻辑。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










