是的,strings.index 返回 -1 表示未找到子串,它是纯计算函数,不返回 error;空串返回 0;大小写敏感;返回字节偏移而非 rune 索引,中文场景需注意 utf-8 编码特性。

strings.Index 返回 -1 是不是说明没找到?
是的,strings.Index 找不到子串时返回 -1,这是它的约定行为,不是错误。别把它和 panic 或异常混淆——它就是个纯计算函数,不抛错、不校验参数。
常见误用:有人看到 -1 就去检查 err != nil,但 strings.Index 根本不返回 error 类型,签名是 func Index(s, substr string) int。
- 空字符串
substr会返回0(Go 规定空串在任意字符串开头“存在”) - 如果
s为空但substr非空,返回-1 - 大小写敏感:
strings.Index("Hello", "h")返回-1,不是0
想忽略大小写查找,strings.Index 不行怎么办?
strings.Index 本身不支持忽略大小写。硬套 strings.ToLower 转换再查,看似简单,但要注意:如果原字符串含 Unicode(比如中文、德语变音符),ToLower 可能改变字节长度,导致后续切片出错或索引错位。
更稳妥的做法是用 strings.IndexFunc 配合 strings.EqualFold 手动扫描:
func indexOfIgnoreCase(s, substr string) int {
if len(substr) == 0 {
return 0
}
for i := 0; i
- 注意边界:循环上限是
len(s) - len(substr),避免越界 panic -
strings.EqualFold正确处理 Unicode 大小写(如 “İ” 和 “i”) - 性能比直接
Index差,但语义准确;高频场景建议预处理或用正则
strings.Index 和 strings.Contains 选哪个?
只关心“是否存在”,用 strings.Contains;需要“从哪开始”,才用 strings.Index。两者底层都做朴素匹配,时间复杂度一样,但 Contains 少一个整数返回值,语义更清晰。
-
strings.Contains(s, "abc")返回bool,适合 if 判断 -
strings.Index(s, "abc") >= 0效果等价,但多算一次整数,还容易漏掉-1判断 - 如果之后还要用这个位置做切片(比如取前缀/后缀),那必须用
Index,别重复扫描
为什么 strings.Index 在中文字符串里有时返回奇怪的位置?
因为 Go 字符串是 UTF-8 字节序列,strings.Index 返回的是**字节偏移量**,不是 rune 索引。中文字符通常占 3 个字节,所以 "你好"[2] 可能 panic,而 strings.Index("你好世界", "世") 返回 6(前两个字共 6 字节),不是 2。
- 要按字符(rune)定位,得先转
[]rune,再遍历:for i, r := range []rune(s) { ... } - 但
strings.Index本身不会帮你解码,它只认字节 - 混合 ASCII 和中文时尤其容易踩坑:
strings.Index("a你好", "好")返回4,不是2
真正要按“第几个字符”操作,别依赖 Index 的返回值直接当 rune 下标用。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











