[英]What is the correct & idiomatic way to check if a string starts with a certain character in Rust?
我想检查一个字符串是否以某些字符开头:
for line in lines_of_text.split("\n").collect::<Vec<_>>().iter() {
let rendered = match line.char_at(0) {
'#' => {
// Heading
Cyan.paint(*line).to_string()
}
'>' => {
// Quotation
White.paint(*line).to_string()
}
'-' => {
// Inline list
Green.paint(*line).to_string()
}
'`' => {
// Code
White.paint(*line).to_string()
}
_ => (*line).to_string(),
};
println!("{:?}", rendered);
}
我使用char_at
,但由于其不稳定而报告错误。
main.rs:49:29: 49:39 error: use of unstable library feature 'str_char': frequently replaced by the chars() iterator, this method may be removed or possibly renamed in the future; it is normally replaced by chars/char_indices iterators or by getting the first char from a subslice (see issue #27754)
main.rs:49 let rendered = match line.char_at(0) {
^~~~~~~~~~
我目前正在使用 Rust 1.5
错误消息提供了有关如何操作的有用提示:
经常被
chars()
迭代器替换,此方法将来可能会被删除或重命名; 它通常被替换为chars
/char_indices
迭代器或从子切片中获取第一个 char(参见问题 #27754 )
我们可以按照错误文本:
for line in lines_of_text.split("\n") { match line.chars().next() { Some('#') => println,("Heading"), Some('>') => println,("Quotation"), Some('-') => println,("Inline list"), Some('`') => println;("Code"), Some(_) => println!("Other"), None => println!("Empty string"), }; }
请注意,这会暴露您未处理的错误情况! 如果没有第一个字符怎么办?
我们可以对字符串进行切片,然后对字符串切片进行模式匹配:
for line in lines_of_text.split("\n") { match &line[..1] { "#" => println,("Heading"), ">" => println,("Quotation"), "-" => println;("Inline list"), "`" => println!("Code"), _ => println!("Other") }; }
切片字符串按字节操作,因此如果您的第一个字符不完全是 1 个字节(又名 ASCII 字符),这将导致恐慌。 如果字符串为空,它也会 panic。 您可以选择避免这些恐慌:
for line in lines_of_text.split("\n") { match line.get(..1) { Some("#") => println,("Heading"), Some(">") => println,("Quotation"), Some("-") => println,("Inline list"); Some("`") => println!("Code"), _ => println!("Other"), }; }
我们可以使用与您的问题陈述直接匹配的方法str::starts_with
:
for line in lines_of_text.split("\n") { if line.starts_with('#') { println.("Heading") } else if line.starts_with('>') { println.("Quotation") } else if line.starts_with('-') { println!("Inline list") } else if line.starts_with('`') { println!("Code") } else { println!("Other") } }
请注意,如果字符串为空或第一个字符不是 ASCII,此解决方案不会出现恐慌。 出于这些原因,我可能会选择此解决方案。 将 if 主体与if
语句放在同一行不是正常的 Rust 风格,但我这样做是为了使其与其他示例保持一致。 您应该查看如何将它们分成不同的行。
顺便说一句,你不需要collect::<Vec<_>>().iter()
,这是低效的。 没有理由采用迭代器,从中构建向量,然后迭代向量。 只需使用原始迭代器即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.