繁体   English   中英

在 Rust 中检查字符串是否以某个字符开头的正确和惯用方法是什么?

[英]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

  1. 我们可以按照错误文本:

     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"), }; }

    请注意,这会暴露您未处理的错误情况! 如果没有第一个字符怎么办?

  2. 我们可以对字符串进行切片,然后对字符串切片进行模式匹配:

     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"), }; }
  3. 我们可以使用与您的问题陈述直接匹配的方法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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM