x4r*_*rkz 0 string vector rust
当你执行s [n],其中s是一个字符串时,为什么你必须遍历字符串才能找到字符串的n字母.(根据https://doc.rust-lang.org/book/strings.html)
根据我的理解,字符串是一个字符数组,一个字符串是一个4字节或4字节的数组.所以越来越第n个信会像这样类似:v [4*n..4*N + 4],其中v是一个向量?
v [i..j]的费用是多少?
我假设v [i..j]的成本是ji,因此s [n]的成本应该是4.
注意:第二版The Rust Programming Language对Rust中的Strings进行了改进和流畅的解释,您可能也希望阅读它.下面的答案虽然仍然准确,但引用了本书的第一版.
我将尝试通过引用本书(https://doc.rust-lang.org/book/strings.html)来澄清这些关于Rust中字符串的误解.
"字符串"是一系列Unicode标量值,编码为UTF-8字节流.保证所有字符串都是UTF-8序列的有效编码.
考虑到这一点,加上UTF-8代码点可变大小(取决于字符1至4字节),在锈的所有字符串,无论它们是&str或String,不是字符数组,并且不能像这样处理.它进一步解释了为什么切片:
因为字符串是有效的UTF-8,所以它们不支持索引:
Run Code Online (Sandbox Code Playgroud)let s = "hello"; println!("The first letter of s is {}", s[0]); // ERROR!!!通常,使用[]访问矢量非常快.但是,因为UTF-8编码字符串中的每个字符都可以是多个字节,所以必须遍历字符串才能找到字符串的nᵗʰ字母.这是一项非常昂贵的操作,我们不想误导.
与问题中提到的不同,人们做不到s[n],因为虽然理论上这将允许我们在恒定时间内获取第n个字节,但该字节不能保证自己有意义.
v [i..j]的费用是多少?
切片的成本实际上是不变的,因为它是在字节级完成的:
您可以使用切片语法获取切片:
Run Code Online (Sandbox Code Playgroud)let dog = "hachiko"; let hachi = &dog[0..5];但请注意,这些是字节偏移,而不是字符偏移.所以这会在运行时失败:
Run Code Online (Sandbox Code Playgroud)let dog = "?????"; let hachi = &dog[0..2];有这个错误:
线程''恐慌'索引0和/或2
?????不在字符边界上'
基本上,切片是可以接受的,并且将产生该字符串的新视图,因此不会制作副本.但是,只有当您完全确定偏移在字符边界方面是正确的时,才应该使用它.
为了迭代字符串的每个字符,您可以改为chars():
let c = s.chars().nth(n);
Run Code Online (Sandbox Code Playgroud)
即使考虑到这一点,请注意,如果您希望处理UTF-8中的字符修饰符(它们本身是标量值但不应单独处理),处理Unicode字符可能并不完全符合您的要求.现在从strAPI中引用:
fn chars(&self) -> Chars返回字符串切片的字符上的迭代器.
由于字符串切片由有效的UTF-8组成,我们可以通过char迭代字符串切片.此方法返回此类迭代器.
重要的是要记住char表示Unicode标量值,并且可能与您对"字符"的概念不符.对字形集群的迭代可能是你真正想要的.
请记住,字符可能与人类对人物的直觉不符:
Run Code Online (Sandbox Code Playgroud)let y = "y?"; let mut chars = y.chars(); assert_eq!(Some('y'), chars.next()); // not 'y?' assert_eq!(Some('\u{0306}'), chars.next()); assert_eq!(None, chars.next());
所述unicode_segmentation板条箱提供了一种手段,以限定字形群集边界:
extern crate unicode_segmentation;
use unicode_segmentation::UnicodeSegmentation;
let s = "a?e?o??\r\n";
let g = UnicodeSegmentation::graphemes(s, true).collect::<Vec<&str>>();
let b: &[_] = &["a?", "e?", "o??", "\r\n"];
assert_eq!(g, b);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |