我试图在 Rust 中索引字符串,但编译器抛出错误。我的代码(欧拉计划问题 4,playground):
fn is_palindrome(num: u64) -> bool {
let num_string = num.to_string();
let num_length = num_string.len();
for i in 0 .. num_length / 2 {
if num_string[i] != num_string[(num_length - 1) - i] {
return false;
}
}
true
}
错误:
error[E0277]: the trait bound `std::string::String: std::ops::Index<usize>` is not satisfied
--> <anon>:7:12
|
7 | if num_string[i] != num_string[(num_length - 1) - i] {
| ^^^^^^^^^^^^^
|
= note: the type `std::string::String` cannot be indexed by `usize`
String
不能被索引是什么原因?那我怎样才能访问数据呢?
最佳答案
是的,索引字符串在 Rust 中不可用。这样做的原因是 Rust 字符串在内部以 UTF-8 编码,因此索引本身的概念会模棱两可,人们会误用它:字节索引很快,但几乎总是不正确(当您的文本包含非 ASCII 符号时,字节索引可能会把你留在一个字符里面,如果你需要文本处理,这真的很糟糕),而字符索引不是免费的,因为 UTF-8 是变长编码,所以你必须遍历整个字符串才能找到所需的代码点。
如果你确定你的字符串只包含 ASCII 字符,你可以在 &str
上使用 as_bytes()
方法返回一个字节切片,然后索引到这个切片:
let num_string = num.to_string();
// ...
let b: u8 = num_string.as_bytes()[i];
let c: char = b as char; // if you need to get the character as a unicode code point
如果确实需要索引代码点,则必须使用 char()
迭代器:
num_string.chars().nth(i).unwrap()
正如我上面所说,这需要遍历整个迭代器直到第 i
个代码元素。
最后,在很多文本处理的情况下,其实是需要和grapheme clusters一起工作的而不是代码点或字节。在 unicode-segmentation 的帮助下crate,你也可以索引到字素簇中:
use unicode_segmentation::UnicodeSegmentation
let string: String = ...;
UnicodeSegmentation::graphemes(&string, true).nth(i).unwrap()
自然地,字素簇索引与遍历整个字符串的要求与索引到代码点具有相同的要求。
关于string - 如何在 Rust 中索引字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24542115/