如何在固定索引处对字符串进行分区?

Dav*_*ker 1 rust

我有一个String(特别是一个SHA1十六进制摘要),我想分成两个子串 - 前两个字符和字符串的其余部分.在Rust中有一个干净的方法吗?

rob*_*nst 14

从 Rust 1.4 开始就有了split_at方法,像这样使用它:

let s = "13e3f28a65a42bf6258cbd1d883d1ce3dac8f085";
let (first, last) = s.split_at(2);

assert_eq!("13", first);
assert_eq!("e3f28a65a42bf6258cbd1d883d1ce3dac8f085", last);
Run Code Online (Sandbox Code Playgroud)

请注意,索引是字节位置,并且必须位于字符边界上。在这种情况下,这是可行的,因为您知道输入字符串是 ASCII。


Vla*_*eev 6

如果您知道您的字符串仅包含ASCII字符(如sha摘要的情况),则可以直接使用切片:

let s = "13e3f28a65a42bf6258cbd1d883d1ce3dac8f085";
let first = &s[..2];  // "13"
let rest = &s[2..];   // "e3f28a65a42bf6258cbd1d883d1ce3dac8f085"
Run Code Online (Sandbox Code Playgroud)

如果您的字符串包含非ASCII字符,它将无法正常工作,因为切片使用字节偏移,并且如果切片中使用的任何索引指向代码点表示的中间,您的程序将会发生混乱.

  • 除了弗拉基米尔所说的,我还是鼓励你为你的SHA1创建一个*新类型*,它表示所有字符都是字母数字(比ASCII更严格).然后,您可以选择以任何有意义的方式在内部存储它(也许是Vec <u8>). (3认同)

oli*_*obk 5

如果您期望两个String而不是切片,则可以使用该chars()方法和一些Iterator方法来获取它们。

let text = "abcdefg".to_string();
let start: String = text.chars().take(2).collect();
let end: String = text.chars().skip(2).collect();
Run Code Online (Sandbox Code Playgroud)

如果您不想进行堆分配,可以使用切片代替:

let start: &str = text.slice_chars(0, 2);
let end: &str = text.slice_chars(2, text.char_len());
Run Code Online (Sandbox Code Playgroud)

请注意,切片版本要求您使用不稳定的 rust(每晚构建,而不是测试版)