strings.contains 是首选,因其底层调用 strings.index、语义明确、性能高且行为确定;但不区分大小写、不支持正则、不处理 unicode 边界,且空字符串始终返回 true。

strings.Contains 为什么是首选?
Go 标准库中检测子串最直接的方式就是 strings.Contains,它底层调用的是 strings.Index,只要 Index 返回值 ≥ 0 就返回 true。它不区分大小写、不支持正则、不处理 Unicode 边界问题——但正因如此,它快且确定。
常见误用是拿 strings.Contains 去做前缀/后缀判断,其实有更语义明确的 strings.HasPrefix 和 strings.HasSuffix,它们内部逻辑更轻量(只比对开头/结尾几个字节),性能略优。
-
strings.Contains("hello world", "lo")→true -
strings.Contains("hello world", "xyz")→false - 传入空字符串
""作为子串时,始终返回true(这是规范定义,不是 bug)
strings.Index 返回 -1 的含义和陷阱
strings.Index 是 Contains 的底层支撑,但它暴露了更多细节:返回子串首次出现的字节索引,没找到就返回 -1。注意,它返回的是字节位置,不是 rune 位置 —— 这在含中文、emoji 的字符串里容易出错。
比如 strings.Index("你好a", "a") 返回 6(因为“你好”占 6 字节),不是 2。如果你需要按字符(rune)定位,得用 strings.IndexRune 或手动遍历 range。
- 不要用
Index == 0判断前缀,改用HasPrefix - 不要用
Index != -1替代Contains,语义不清且多一次整数比较 - 若需多次查找,
strings.Index每次都从头扫,不如用strings.FieldsFunc或正则预处理
case-insensitive 检测不能靠 strings.ToLower
想忽略大小写查子串,很多人写 strings.Contains(strings.ToLower(s), strings.ToLower(sub))。这在 ASCII 场景下可行,但遇到土耳其语 i/I、德语 ß、或带重音符号的字符时,ToLower 可能产生非预期映射,且每次调用都分配新字符串。
更稳妥的做法是用 strings.EqualFold 手动扫描:先用 strings.Index 找到所有可能位置,再对每个候选子串调用 strings.EqualFold(candidate, sub)。标准库没提供现成函数,因为「忽略大小写的子串搜索」本身场景有限,且易引发 locale 依赖问题。
- 简单场景可用
strings.Contains(strings.ToLower(s), strings.ToLower(sub)),但别用于用户输入或国际化文本 -
strings.EqualFold是 Go 唯一保证 Unicode 大小写等价的函数,但它只比较两个完整字符串 - 真正要支持 i18n 子串搜索,得引入
golang.org/x/text/search包,它封装了 collation 规则
strings.ContainsAny 和 ContainsRune 完全不是一回事
strings.ContainsAny 判断的是「字符串中是否包含任意一个指定字符」,不是子串。例如 strings.ContainsAny("hello", "aeiou") 返回 true,因为它在找元音字母,而非子串 "aeiou"。
而 strings.ContainsRune 是专为单个 Unicode 码点设计的,比如检查字符串里有没有 emoji:strings.ContainsRune("hello ?", '?')。它比 strings.Contains 更精确,因为不会把 emoji 拆成多个字节误判。
-
ContainsAny("abc", "xyz")→false;ContainsAny("abc", "bc")→true -
ContainsRune("cafe\u0301", '\u0301')→true(组合字符),但Contains("cafe\u0301", "\u0301")也成立,只是语义不同 - 别用
ContainsAny实现子串搜索,它的算法是哈希表查字符集,完全不考虑顺序
ContainsAny 的「任意字符」本质——写错一次,测试可能刚好通过,线上遇到多语言数据才暴露。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











