strings.contains 是 go 中判断子串是否存在的最直接方式,仅支持逐字节精确匹配、不区分大小写、不处理 unicode 边界,适用于 ascii 或编码一致的简单场景。

strings.Contains 是 Go 标准库中判断子串是否存在的最直接方式,它返回 bool,不区分大小写、不支持正则、也不处理 Unicode 边界问题——用对场景就非常可靠,用错就默默返回 false。
什么时候该用 strings.Contains?
适用于纯 ASCII 或已知编码一致的简单包含判断,比如检查日志行是否含关键词、配置项是否启用某标志、HTTP 请求路径是否以 /api/ 开头。
- 输入都是
string类型,不能传[]byte(要用bytes.Contains) - 匹配是**逐字节比较**,不是按 rune(字符),所以含中文、emoji 时只要源字符串和子串编码一致(都为 UTF-8),就没问题
- 它**不忽略大小写**:
strings.Contains("Hello", "hello")→false
常见错误:误以为它支持模糊或前缀匹配
它只做「是否存在连续子串」判断,不等价于 strings.HasPrefix 或 strings.HasSuffix,也不支持通配符。
- 想判断开头?用
strings.HasPrefix(s, prefix),别写strings.Contains(s, prefix) && strings.Index(s, prefix) == 0 - 想忽略大小写?必须先转小写:
strings.Contains(strings.ToLower(s), strings.ToLower(substr)) - 想匹配单词边界(如 "is" 不匹配 "this")?
strings.Contains做不到,得用regexp包
性能和替代方案对比
在大多数场景下,strings.Contains 是零分配、O(n) 时间复杂度的最优解。但要注意:
立即学习“go语言免费学习笔记(深入)”;
- 如果频繁判断同一字符串是否包含多个子串,考虑用
strings.Index一次扫描 + 手动比对,避免多次遍历 - 如果子串长度为 0(空字符串),
strings.Contains恒返回true—— 这是定义行为,不是 bug - 如果要同时检查多个关键词,别连写
strings.Contains(a, x) || strings.Contains(a, y) || strings.Contains(a, z),可封装成循环或用strings.FieldsFunc配合map[string]bool查表
func containsAny(s string, substrs []string) bool {
for _, sub := range substrs {
if strings.Contains(s, sub) {
return true
}
}
return false
}
容易被忽略的细节:nil 和空字符串
strings.Contains 接收的是两个 string,Go 中 string 永远不会是 nil,所以无需判空指针;但空字符串 "" 是合法输入:
-
strings.Contains("", "")→true -
strings.Contains("abc", "")→true -
strings.Contains("", "a")→false
如果你的业务逻辑里“空关键词”应视为无效条件,需要在调用前显式过滤,而不是依赖函数行为。










