簡體   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