strings.Contains 是最直接安全的子串判断方式,返回 bool 值,区分大小写、朴素匹配;不适用于格式验证或内容提取,空字符串为 true,非空子串在空串中为 false。
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 返回 int 就想用 != -1 判断,或者用 strings.Count 看是否 > 0 —— 这些都能工作,但没必要,且有隐含成本或语义偏差。
strings.Index 
strings.Count 会遍历完整个字符串统计全部出现次数,而 Contains 找到第一个就返回,短路更快strings.Count("aaaa", "aa") 返回 3(重叠计数),但 Contains 只关心存在性,逻辑更干净strings.Contains 本身不支持忽略大小写,强行转全小写再查(strings.Contains(strings.ToLower(s), strings.ToLower(substr)))看似简单,但要注意:
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,无需担心越界 panicfmt.Sprintf 再传给 Contains),直接用字面量或已有变量真正复杂的情况往往不在“找不找得到”,而在“找得到之后要不要继续处理”——比如多个关键词共存、子串嵌套、或需要排除某些上下文。这时候 Contains 只是第一步,别指望它包揽全部逻辑。