rust: how to bind match in a loop

I take input string from user, match it with characters k,f or c. if anything else, returns "input k,f or c".

How do i put "input k,f or c" in a loop so that when the user inputs correct string, i can extract value out of the loop.

my code: (it compiles but not the way i want. can’t interact with rust playground terminal but compiles)

fn main() {
    println!("K : for Kelvin    C : for Celsius     F : for Fahrenheit : ");
    
    let mut unit = String::new();
    std::io::stdin().read_line(&mut unit).expect("Failed to read line");
    
    let unit = unit.trim().to_uppercase();
    println!("unit is {unit} -before match");// this line is for test
    
    let unit:&str = match &*unit{
        "K"=>"K",
        "F"=>"F",
        "C"=>"C",
         _ =>{println!("input k,f or c");return},
    };
    println!("unit is {unit} after match");// this line is for test
    
}

I tried putting the block in loop{} and break at error catcher _=> and return unit value.
But i could not catch the value of unit outside of loop{}. Could not compile.

fn main() {
    Loop{
    println!("K : for Kelvin    C : for Celsius     F : for Fahrenheit : ");
    let mut unit = String::new();
    std::io::stdin().read_line(&mut unit).expect("Failed to read line");
    let unit = unit.trim().to_uppercase();
    println!("unit is {unit} -before match");// this line is for test
    
    let unit:&str = match &*unit{
        "K"=>"K",
        "F"=>"F",
        "C"=>"C",
         _ =>{println!("input k,f or c");break unit},
    };
  }
    println!("unit is {unit} after match");// this line is for test
    
}

>Solution :

You want the exact opposite of your second attempt, you want to break (i.e. exit the loop) once the user put in something valid and continue (i.e. repeat the loop) if they don’t:

fn main() {
    let unit = loop {
        println!("K : for Kelvin    C : for Celsius     F : for Fahrenheit : ");
        let mut unit = String::new();
        std::io::stdin()
            .read_line(&mut unit)
            .expect("Failed to read line");
        let unit = unit.trim().to_uppercase();
        println!("unit is {unit} before match"); // this line is for test

        break match unit.as_str() {
            "K" => "K",
            "F" => "F",
            "C" => "C",
            _ => continue,

        };
    };
    println!("unit is {unit} after match"); // this line is for test
}

Leave a Reply