2016-01-01 9 views
9

Voglio controllare se una stringa inizia con alcuni caratteri:Qual è il modo corretto e idiomatico per verificare se una stringa inizia con un certo carattere 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); 
} 

ho usato char_at, ma segnala un errore a causa della sua instabilità.

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

Attualmente sto usando Rust 1.5

risposta

19

Il messaggio di errore fornisce utili suggerimenti su cosa fare:

spesso sostituita dalla chars() iteratore, questo metodo può essere rimosso o eventualmente rinominato nel futuro; è normalmente sostituito da chars/char_indices iteratori o ottenendo il primo carattere da un subslice (vedi issue #27754)

  1. abbiamo potuto seguire il testo di errore:

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

    Si noti che questo espone un condizione di errore che non stavi gestendo! Cosa succede se lo non era il primo carattere?

  2. Potremmo fetta la corda e poi pattern match su fette di stringa:

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

    affettare una stringa opera da byte e quindi questo sarà prendere dal panico se il tuo primo personaggio non è esattamente 1 byte (aka un carattere ASCII). Sarà anche panico se la stringa è vuota.

  3. Potremmo utilizzare il metodo che è una corrispondenza diretta alla vostra dichiarazione del problema, 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") } 
    } 
    

    Si noti che questa soluzione non prendere dal panico se la stringa è vuota o se il primo carattere non è ASCII. Probabilmente sceglierei questa soluzione per queste ragioni. Mettere i corpi se sulla stessa linea dell'istruzione if non è normale stile Rust, ma lo ho messo in questo modo per lasciarlo coerente con gli altri esempi. Si dovrebbe guardare per vedere come li separa in diverse linee sembra.


Per inciso, non è necessario collect::<Vec<_>>().iter(), questo è solo inefficiente. Non c'è motivo di prendere un iteratore, costruire un vettore da esso, quindi scorrere il vettore. Basta usare l'iteratore originale.

+0

Perfetto. Grazie! – rilut

+0

Sì, pensavo che anche la raccolta sul vettore fosse inefficiente. Non sapevo che Split fosse lo stesso iteratore di iter. Posso chiederti, che è più veloce dalle tue soluzioni? O la loro velocità è più o meno la stessa? – rilut

+1

@rilut puoi chiedere, ma non so la risposta^_ ^. Forse qualcuno interverrà, ma potresti anche fare alcuni test delle prestazioni nella tua app e vedere di sicuro. Probabilmente * suppongo * che siano tutti uguali. – Shepmaster

Problemi correlati