String 如何从字符串中提取第一个字符?

String 如何从字符串中提取第一个字符?,string,rust,String,Rust,我想得到a的第一个字符。该方法目前是不稳定的 我提出了以下建议,但获取单个字符而不使用向量的其余部分似乎有些过分: let text = "hello world!"; let char_vec: Vec<char> = text.chars().collect(); let ch = char_vec[0]; 让text=“你好,世界!”; 让char_vec:vec=text.chars().collect(); 设ch=char_-vec[0]; UTF-

我想得到a的第一个字符。该方法目前是不稳定的

我提出了以下建议,但获取单个字符而不使用向量的其余部分似乎有些过分:

let text = "hello world!";
let char_vec: Vec<char> = text.chars().collect();
let ch = char_vec[0];
让text=“你好,世界!”;
让char_vec:vec=text.chars().collect();
设ch=char_-vec[0];

UTF-8没有定义“字符”是什么,因此它取决于您想要什么。在本例中,
char
s是Unicode标量值,因此
&str
的第一个
char
将在一到四个字节之间

如果只需要第一个
字符
,则不要收集到
向量
,只需使用迭代器:

让text=“你好,世界!”;
设ch=text.chars().next().unwrap();
或者,您可以使用迭代器的方法:

ch=text.chars().nth(0.unwrap();

请记住,传递给第n个
的索引前面的元素将从迭代器中使用。

接受的答案有点难看

let text = "hello world!";

let ch = &text[0..1]; // this returns "h"

我编写了一个函数,返回一个
&str
的头部和其余部分:

fn car_cdr(s: &str) -> (&str, &str) {
    for i in 1..5 {
        let r = s.get(0..i);
        match r {
            Some(x) => return (x, &s[i..]),
            None => (),
        }
    }

    (&s[0..0], s)
}
像这样使用它:

let (first_char, remainder) = car_cdr("test");
println!("first char: {}\nremainder: {}", first_char, remainder);
输出如下所示:

第一个字符:t
余数:美国东部标准时间

它适用于大于1字节的字符。

您可能还需要查看是否确实需要第一个图形。这会给出
n
th代码单位,但
char\u at
给出从字节
n
开始的代码单位。后者更有用,因为大多数字符串操作处理字节索引。这相当于
char\u at
(也是常数时间):
text[i...chars().next().unwrap()
@delnan:我认为在
处实际使用
char\u有点危险,因为索引可能在代码单元中。@delnan:是的,代码点索引在O(1)中无论如何都不起作用。但是,当有人要求输入第n个字符时,他们可能会要求输入第n个码点或第n个字符集,但他们不太可能要求输入第n个字节。这是否可以推广到第n个字符,而不仅仅是第一个字符?对于非ASCII数据,这个答案是完全错误的。试试
&”日本語"[0..1]
也许写下公认答案的史蒂夫·克拉布尼克(Steve Klabnik)应该更新他在Rust网站上的书,因为它显示了这种精确的方法()。这本书的那一章简要介绍了(“
world
将是一个切片,其中包含指向
s
的第6字节的指针和长度值5”,我的重点)在中。这可能不是OP想要的。但它帮助我获得了作为字符串的第一个字符。这正是我想要的!谢谢,@FeFiFoFu:)似乎。Shepmaster-你的版本确实更简单。但是,我担心chars()函数-在我看来,它似乎扫描整个字符串并将其解析为向量或其他内容,而我的代码最多只查看字符串的前4个字符。但是,也许我误解了chars()的工作原理?对不起,我的意思是说“前4个字节”不是“前4个字符”@Sean,你可能现在已经知道了,而是chars()返回一个迭代器。迭代器是惰性计算的(零成本,意味着编译器在编译时重写它们),因此它实际上应该是非常有效的。