strings.Contains 是最直接安全的子串判断方式,返回 bool 值,区分大小写、朴素匹配;不适用于格式验证或内容提取,空字符串为 true,非空子串在空串中为 false。

strings.Contains 判断子串存在的基本用法
Go 标准库 strings.Contains 是最直接、最安全的子串判断方式,返回 bool 值,不 panic,也不依赖正则。它区分大小写,且只做朴素匹配(非重叠、无边界限制)。
常见误用是拿它去“验证格式”或“提取内容”,但它只回答“有没有”,不关心位置或上下文。
-
strings.Contains("hello world", "lo")→true -
strings.Contains("Hello World", "hello")→false(大小写敏感) -
strings.Contains("", "a")→false(空字符串不含任何非空子串) -
strings.Contains("abc", "")→true(任意字符串都包含空字符串)
为什么不用 strings.Index 或 strings.Count 替代
有人看到 strings.Index 返回 int 就想用 != -1 判断,或者用 strings.Count 看是否 > 0 —— 这些都能工作,但没必要,且有隐含成本或语义偏差。
-
strings.Index多算了一次位置查找,语义上你并不需要下标,白耗 CPU -
strings.Count会遍历完整个字符串统计全部出现次数,而Contains找到第一个就返回,短路更快 -
strings.Count("aaaa", "aa")返回3(重叠计数),但Contains只关心存在性,逻辑更干净
大小写不敏感的替代方案
strings.Contains 本身不支持忽略大小写,强行转全小写再查(strings.Contains(strings.ToLower(s), strings.ToLower(substr)))看似简单,但要注意:
立即学习“go语言免费学习笔记(深入)”;
- 对 ASCII 字符安全;对 Unicode(如德语 ß、土耳其语 İ)可能出错,
strings.ToLower不是完全等价于“忽略大小写比较” - 如果只是简单英文场景,可以接受;否则应改用
strings.EqualFold配合切片遍历,或借助bytes.EqualFold+strings.Index组合
func ContainsFold(s, substr string) bool {
for i := 0; i <= len(s)-len(substr); i++ {
if bytes.EqualFold([]byte(s[i:i+len(substr)]), []byte(substr)) {
return true
}
}
return false
}
性能与边界情况注意点
strings.Contains 底层调用的是 runtime 的优化汇编(如 amd64 上用 AVX2),在大多数场景下足够快。但仍有几个容易被忽略的细节:
- 当
substr长度为 0 时恒返回true,这符合规范,但若业务逻辑中“空子串”应视为无效输入,需额外校验 - 子串长度大于主串时立即返回
false,无需担心越界 panic - 在 hot path 中频繁调用时,避免重复构造临时字符串(比如先
fmt.Sprintf再传给Contains),直接用字面量或已有变量
真正复杂的情况往往不在“找不找得到”,而在“找得到之后要不要继续处理”——比如多个关键词共存、子串嵌套、或需要排除某些上下文。这时候 Contains 只是第一步,别指望它包揽全部逻辑。










