【发布时间】:2015-11-17 20:20:28
【问题描述】:
我目前正在从 Rust 移植一个 Python 库,但发现一行我无法找到正确的“翻译”:
right = s.index(sep, left)
其中right 是在字符串s 中找到的第一个sep 实例的索引,该索引位于索引left 之后。
这里有一个简单的例子:
Python 3
>>> s = "Hello, my name is erip and my favorite color is green."
>>> right = s.index("my", 10) # Find index of first instance of 'my' after index 10
>>> print right
27
>>> print s[27:]
my favorite color is green.
我在 Rust 中的尝试是:
// s: &str, sep: &str, left: usize
let right = s[left..].find(sep).unwrap() + left;
这将在left 之后的字节中搜索sep。这seems to work 使用 ASCII 字符时。不过,使用 Unicode 时似乎有问题:
Python 3
>>> s = "Hello, mÿ name is erip and mÿ favorite color is green."
>>> right = s.index("mÿ", 10)
>>> print(right)
27
fn main() {
let sep: &str = "mÿ";
let left: usize = 10;
let s: &str = "Hello, mÿ name is erip and mÿ favorite color is green.";
let right = s[left..].find(sep).unwrap() + left;
println!("{}", right); //prints 28
}
我意识到 Python 2 也会给出 28,因为它本身不支持 Unicode,但我想模仿 Python 3 的结果。
问题在于 Rust 中的 usize 指的是字符串中 bytes 的数量,因为“mÿ”实际上需要 3 个字节来编码。如何在 Rust 中获得这种期望的行为?
我正在使用rustc 1.4.0。
【问题讨论】:
-
因为
usize[...] 指的是字符串中的字节数——在这种情况下确实如此,但并非普遍如此。usize是机器大小的无符号整数,适用于计算受机器内存限制的事物的数量。 -
在风格上,没有理由在
main中使用任何类型声明。都可以推断出来。 -
我怀疑是 X/Y 问题:该索引之后可能被其他东西使用,因此索引本身的单位(以及值)并不重要(无论是字形、代码点还是字节)只要该单元由消费者共享 => 你真的想在代码点中有一个索引吗?还是字形?或者,只要消费者也可以适应字节,字节会起作用吗?
-
@MatthieuM。我在标记器中使用它 - 我想要字素中的索引。即,我不需要担心字符串中的 bytes 的数量。而是字符的位置,与编码方案无关。
-
@Shepmaster:视情况而定,有时您可能需要字素中的索引;例如,当在下一行用“~~~”为文本的一部分加下划线时,您不需要根据终端中的字节或代码点进行推理,而是根据字素(假设一个等宽字体,常见于终端)。对于分词器,我不会对同时需要字节索引和字素索引感到惊讶。