你切的不是“第几个字”,而是第几个字节

Rust 的 String 保存 UTF‑8。英文、汉字和 emoji 在屏幕上都像一个符号,在内存里却可能占 1、3、4 个字节。移动切片边界,看看编译器为什么不肯让你从一个字符的半腰切下去。

0字节 · Rust 的 s.len()
0Unicode 标量值 · s.chars().count()
0合法边界

UTF‑8 字节带

十六进制字节;下标从 0 开始

模拟 &s[start..end]

下拉框故意列出每个字节位置,包括字符内部的危险位置。黄色字节是当前选区。

为什么不能写 s[0]

索引通常暗示“固定成本地拿到一个元素”。但 UTF‑8 字符长度不固定,第 0 个“字符”到底是字节、Unicode 标量值,还是用户眼里的完整字形?Rust 不替你猜,所以 String 不提供整数索引。

需要逐个处理时怎么选?

协议和文件格式关心原始数据时用 bytes();按 Unicode 标量值遍历时用 chars()。用户眼里的一个字形可能由多个标量值组成,严肃的文本界面还需要字素簇算法。