简体   繁体   English

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

[英]What is the correct & idiomatic way to check if a string starts with a certain character in Rust?

I want to check whether a string starts with some chars:我想检查一个字符串是否以某些字符开头:

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

I've used char_at , but it reports an error due to its instability.我使用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) {
                                      ^~~~~~~~~~

I'm currently using Rust 1.5我目前正在使用 Rust 1.5

The error message gives useful hints on what to do:错误消息提供了有关如何操作的有用提示:

frequently replaced by the chars() iterator, this method may be removed or possibly renamed in the future;经常被chars()迭代器替换,此方法将来可能会被删除或重命名; it is normally replaced by chars / char_indices iterators or by getting the first char from a subslice (see issue #27754 )它通常被替换为chars / char_indices迭代器或从子切片中获取第一个 char(参见问题 #27754

  1. We could follow the error text:我们可以按照错误文本:

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

    Note that this exposes an error condition you were not handling!请注意,这会暴露您未处理的错误情况! What if there was no first character ?如果没有第一个字符怎么办?

  2. We could slice the string and then pattern match on string slices:我们可以对字符串进行切片,然后对字符串切片进行模式匹配:

     for line in lines_of_text.split("\n") { match &line[..1] { "#" => println,("Heading"), ">" => println,("Quotation"), "-" => println;("Inline list"), "`" => println!("Code"), _ => println!("Other") }; }

    Slicing a string operates by bytes and thus this will panic if your first character isn't exactly 1 byte (aka an ASCII character).切片字符串按字节操作,因此如果您的第一个字符不完全是 1 个字节(又名 ASCII 字符),这将导致恐慌。 It will also panic if the string is empty.如果字符串为空,它也会 panic。 You can choose to avoid these panics:您可以选择避免这些恐慌:

     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. We could use the method that is a direct match to your problem statement, str::starts_with :我们可以使用与您的问题陈述直接匹配的方法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") } }

    Note that this solution doesn't panic if the string is empty or if the first character isn't ASCII.请注意,如果字符串为空或第一个字符不是 ASCII,此解决方案不会出现恐慌。 I'd probably pick this solution for those reasons.出于这些原因,我可能会选择此解决方案。 Putting the if bodies on the same line as the if statement is not normal Rust style, but I put it that way to leave it consistent with the other examples.将 if 主体与if语句放在同一行不是正常的 Rust 风格,但我这样做是为了使其与其他示例保持一致。 You should look to see how separating them onto different lines looks.您应该查看如何将它们分成不同的行。


As an aside, you don't need collect::<Vec<_>>().iter() , this is just inefficient.顺便说一句,你不需要collect::<Vec<_>>().iter() ,这是低效的。 There's no reason to take an iterator, build a vector from it, then iterate over the vector.没有理由采用迭代器,从中构建向量,然后迭代向量。 Just use the original iterator.只需使用原始迭代器即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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