服务刚上线,一个查询接口偶发 500。日志里一行 panic: runtime error: index out of range,后面跟着位置和长度。看代码,取的是字符串第四个字符,而传进来的值只有三个字符。

这类错误的意思很直白:你按位置取字符,但那个位置超出了字符串的实际长度。索引从 0 开始,长度 3 的字符串,合法下标只有 0、1、2,写成 3 就越界了。

三个语言里长得不一样

  • Go:panic: runtime error: index out of range,不 recover 就整个 goroutine 挂掉,进程里的其他请求也受影响
  • Python:IndexError: string index out of range,脚本直接中断
  • Java:StringIndexOutOfBoundsException,属于运行时异常,编译期不报

名字不同,处理思路一样:取之前判断长度,或者用不会越界的 API。substring 这类方法在 Java 里是左闭右开,结束位置可以等于长度,这点和直接取下标不同,写的时候容易下意识多减一。

中文和表情符号会多算

Go 里 len 返回的是字节数,一个汉字三字节。字符串 hello中文 的字节长度是 11,字符长度是 7。按下标取到的是字节,可能取到半个汉字,输出就是乱码。要按字符处理,先转成 rune 切片。

rs := []rune(s); if len(rs) > 3 { fmt.Println(string(rs[3])) }

Python 3 的字符串是按字符算的,但用 bytes 就会变回字节。Java 的 char 是 UTF-16 单元,一个 emoji 占两个,length 和肉眼看到的字符数对不上,截断用户昵称时特别容易出错,可能把一个表情切成两半。

真正的修法是加边界检查,别用异常当流程控制。解析固定格式的报文,先校验长度再取值,报错信息里带上原始内容和期望长度,下次排查能少花两小时。