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

我想得到一个 std::str的第一个字符。方法 char_at()目前是不稳定的,因为是 String::slice_chars

我已经想出了下面的方法,但是只得到一个字符而不使用向量的其余部分似乎有些过分:

let text = "hello world!";
let char_vec: Vec<char> = text.chars().collect();
let ch = char_vec[0];
92677 次浏览

UTF-8没有定义什么是“字符”,因此它取决于您想要什么。在这种情况下,char是 Unicode 标量值,因此 &str的第一个 char将在1到4个字节之间。

如果您只想要第一个 char,那么不要收集到 Vec<char>中,只需使用迭代器:

let text = "hello world!";
let ch = text.chars().next().unwrap();

或者,您可以使用迭代器的 nth方法:

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

请记住,传递给 nth的索引之前的元素将从迭代器中使用。

接受的答案有点难看!

let text = "hello world!";


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

I wrote a function that returns the head of a &str and the rest:

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);

输出结果如下:

first char: t
remainder: est

它可以很好地处理大于1字节的字符。

对于这种情况,如果有类似于 Haskell 的 head function尾部功能的东西就好了。

我编写这个函数是为了同时起到 headtail的作用(与精确的实现不匹配)

pub fn head_tail<T: Iterator, O: FromIterator<<T>::Item>>(iter: &mut T) -> (Option<<T>::Item>, O) {
(iter.next(), iter.collect::<O>())
}

用法:

// works with Vec<i32>
let mut val = vec![1, 2, 3].into_iter();
println!("{:?}", head_tail::<_, Vec<i32>>(&mut val));
// works with chars in two ways
let mut val = "thanks! bedroom builds YT".chars();
println!("{:?}", head_tail::<_, String>(&mut val));
// calling the function with Vec<char>
let mut val = "thanks! bedroom builds YT".chars();
println!("{:?}", head_tail::<_, Vec<char>>(&mut val));

注意 : 如果迭代器为空,head _ tail 函数不会返回 panic!如果这与 Haskell 的 head/tail 输出匹配,那么如果迭代器为空,就会引发异常.也可以使用迭代 trait 来更好地兼容其他类型。

使用字符串的其余部分从字符串 好的中取出第一个字符:

let text = "hello world!";
let ch = text.chars().take(1).last().unwrap();

If you only want to test for it, you can use starts_with():

"rust".starts_with('r')
"rust".starts_with(|c| c == 'r')