2016-01-01 5 views
9

Ich möchte überprüfen, ob eine Zeichenfolge mit einigen Zeichen beginnt:Was ist die korrekte und idiomatische Art zu prüfen, ob eine Zeichenfolge in Rust mit einem bestimmten Zeichen beginnt?

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

ich char_at verwendet habe, aber es meldet einen Fehler aufgrund seiner Instabilität.

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) { 
             ^~~~~~~~~~ 

ich zur Zeit mit Rust 1,5

Antwort

19

Die Fehlermeldung gibt nützliche Hinweise, was zu tun ist:

häufig durch den chars() Iterator ersetzt dieses Verfahren entfernt werden kann oder möglicherweise umbenannt in der Zukunft; es normalerweise von chars/char_indices Iteratoren oder indem man das erste Zeichen von einem subslice (siehe issue #27754)

  1. Wir haben den Fehlertext folgen konnte Fassung:

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

    Beachten Sie, dass dies ein aussetzt Fehlerzustand, den Sie nicht bearbeitet haben! Was ist, wenn kein erstes Zeichen war?

  2. Wir konnten Scheibe die Zeichenfolge und dann Mustererkennung auf String-Scheiben:

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

    einen String Slicing arbeitet von Bytes und somit wird diese Panik, wenn Ihre erste Zeichen nicht genau 1 Byte (aka ein ASCII-Zeichen). Es wird auch in Panik geraten, wenn die Zeichenfolge leer ist.

  3. Wir könnten die Methode verwenden, die eine direkte Anpassung an Ihre Problemstellung ist, 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") } 
    } 
    

    Beachten Sie, dass diese Lösung nicht in Panik, wenn die Zeichenfolge leer ist oder wenn das erste Zeichen nicht ist ASCII. Ich würde diese Lösung wahrscheinlich aus diesen Gründen wählen. Putting die Körper If auf der gleichen Linie wie die if Aussage ist nicht normal Rust Stil, aber ich habe es so gesagt, um es mit den anderen Beispielen konsistent zu lassen. Sie sollten sehen, wie die Trennung auf verschiedene Linien aussieht.


Als Nebenwirkung Sie collect::<Vec<_>>().iter() nicht benötigen, ist dies nur ineffizient. Es gibt keinen Grund, einen Iterator zu nehmen, einen Vektor daraus zu bauen und dann über den Vektor zu iterieren. Verwenden Sie einfach den ursprünglichen Iterator.

+0

Perfekt. Vielen Dank! – rilut

+0

Ja, ich dachte, das Sammeln zu Vektor war auch ineffizient. Ich wusste nicht, Split ist der gleiche Iterator wie iter. Darf ich fragen, was ist schneller von Ihren Lösungen? Oder ist ihre Geschwindigkeit ungefähr gleich? – rilut

+1

@rilut können Sie fragen, aber ich kenne die Antwort nicht^_ ^. Vielleicht wird jemand hereinspielen, aber Sie könnten auch einige Leistungstests in Ihrer App durchführen und sicher sehen. Ich würde wahrscheinlich * raten *, dass sie alle gleich sind. – Shepmaster

Verwandte Themen