Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

string

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.

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

like image 598
luthfianto Avatar asked Jan 01 '16 20:01

luthfianto


People also ask

What does to correct mean?

Verb. correct, rectify, emend, remedy, redress, amend, reform, revise mean to make right what is wrong. correct implies taking action to remove errors, faults, deviations, defects. correct your spelling rectify implies a more essential changing to make something right, just, or properly controlled or directed.

What word is correct?

accurate, appropriate, equitable, exact, factual, legitimate, perfect, precise, proper, strict, true, acceptable, careful, alter, amend, cure, improve, mend, rectify, redress.

What is the correct definition of English?

The variety of English that is generally acknowledged as the model for the speech and writing of educated speakers, especially when contrasted with speech varieties that are limited to or characteristic of a certain region or social group.

What is the noun of correct?

Word family (noun) correction correctness corrective (adjective) correct ≠ incorrect corrective (verb) correct (adverb) correctly ≠ incorrectly.


1 Answers

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; it is normally replaced by chars/char_indices iterators or by getting the first char from a subslice (see issue #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 (a.k.a. an ASCII character). It will also panic if the string is empty. 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:

    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. 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. 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. There's no reason to take an iterator, build a vector from it, then iterate over the vector. Just use the original iterator.

like image 87
Shepmaster Avatar answered Sep 20 '22 22:09

Shepmaster