Rust温度转换器问题:如何不重启循环仅校验输入单位
Rust温度转换器优化需求
我用Rust写了个温度转换器,支持Kelvin、Celsius、Fahrenheit三种单位互转。现在有个问题:
- 程序先要求输入数值,非数字时重启循环,这部分逻辑没问题
- 输入数值后要求输入单位(必须是K、C、F),但输入非法单位时,程序会直接跳回开头重新输入数值,而不是只重新提示输入单位
我想实现:非法单位输入时只重新要求输入单位,不重启整个流程。尝试用if let结合match没成功,同时对match表达式、作用域和loop返回值理解有困惑。
主代码
fn main() { println!("\nWelcome. This is Temperature-Converter\n"); println!("I work with Fahrenheit, Celsius and Kelvin"); println!("\nPlease Input the Value you want to convert: "); loop{ let mut value = String::new(); std::io::stdin().read_line(&mut value).expect("Failed to read line"); let value:f32 = match value.trim().parse(){ Ok(num) => num, Err(_) => { println!("please input value in number(s)."); continue; } }; println!("Thank You, I have the value: {value}.\nPlease provide it's respective unit of measurement."); 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(); let unit = match unit.as_str() { "K"=>"K", "F"=>"F", "C"=>"C", _=>{ println!("please input K, F or C for Kelvin, Fahrenheit or Celcius respectively."); continue; } }; println!("Thank you for your input. I see that you want to convert {value} degree {unit}."); println!("Please wait while i provide all possible conversions.\nThis will be quick."); if unit == "K"{ let value_c = value-273.15; let value_f = (((value-273.15)*9.0)+(32.0*5.0))/5.0; println!("{value}{unit} is converted to: {value_c}C and {value_f}F"); println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!"); break; } else if unit == "C"{ let value_k = value+273.15; let value_f = (value*(9.0/5.0))+32.0; println!("{value}{unit} is converted to:{value_k}K and {value_f}F"); println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!"); break; } else if unit == "F"{ let value_k = (((value-32.0)*5.0)/9.0)+273.15; let value_c = ((value-32.0)*5.0)/9.0; println!("{value}{unit} is Converted to: {value_k}K and {value_c}C"); println!("Thank You for using Temperature-Converter. It was a pleasure to assist you. Byee!!"); break; }; } }
尝试的代码片段
if let unit = match unit.as_str() { "K"=>"K", "F"=>"F", "C"=>"C", _=>{println!("please input K, F or C for Kelvin, Fahrenheit or Celcius respectively.")} };
解决方案
核心思路是把单位输入逻辑单独放到内层loop中,直到用户输入合法单位再退出内层循环,避免回到数值输入步骤。
修改后的完整代码
fn main() { println!("\nWelcome. This is Temperature-Converter\n"); println!("I work with Fahrenheit, Celsius and Kelvin"); println!("\nPlease Input the Value you want to convert: "); loop { let mut value = String::new(); std::io::stdin().read_line(&mut value).expect("Failed to read line"); let value: f32 = match value.trim().parse() { Ok(num) => num, Err(_) => { println!("please input value in number(s)."); continue; } }; println!("Thank You, I have the value: {value}.\nPlease provide it's respective unit of measurement."); println!("K : for Kelvin C : for Celsius F : for Fahrenheit : "); // 内层循环专门处理单位输入,直到合法为止 let unit = loop { let mut unit = String::new(); std::io::stdin().read_line(&mut unit).expect("Failed to read line"); let unit = unit.trim().to_uppercase(); match unit.as_str() { "K" | "F" | "C" => break unit, // 合法单位,退出内层循环并返回该值 _ => println!("please input K, F or C for Kelvin, Fahrenheit or Celcius respectively."), } }; println!("Thank you for your input. I see that you want to convert {value} degree {unit}."); println!("Please wait while i provide all possible conversions.\nThis will be quick."); // 用match替换if-else,代码更简洁 match unit.as_str() { "K" => { let value_c = value - 273.15; let value_f = (((value - 273.15) * 9.0) + (32.0 * 5.0)) / 5.0; println!("{value}{unit} is converted to: {value_c}C and {value_f}F"); } "C" => { let value_k = value + 273.15; let value_f = (value * (9.0 / 5.0)) + 32.0; println!("{value}{unit} is converted to:{value_k}K and {value_f}F"); } "F" => { let value_k = (((value - 32.0) * 5.0) / 9.0) + 273.15; let value_c = ((value - 32.0) * 5.0) / 9.0; println!("{value}{unit} is Converted to: {value_k}K and {value_c}C"); } _ => unreachable!(), // 内层循环已确保单位合法,此处永远不会执行 } println!("Thank You for using Temperature-Converter. It was a pleasure to assist you. Byee!!"); break; } }
关键逻辑说明
内层loop处理单位输入:
把单位输入逻辑封装在独立loop中,合法输入时用break unit退出循环并返回单位值;非法输入仅打印提示,继续内层循环,不会触发外层continue回到数值输入步骤。match表达式与loop返回值:
- Rust的
match必须覆盖所有分支,或用_处理剩余情况。这里内层match已过滤非法单位,外层match的_分支用unreachable!()标记,明确该分支不可能执行。 loop可以通过break 返回值向外传递数据,这是实现内层循环获取合法输入的核心,返回的单位值直接赋值给外层的unit变量。
- Rust的
作用域问题:
内层loop中的unit变量作用域仅限于内层循环,退出时返回的合法单位字符串会被外层变量接收,不存在作用域冲突问题。
内容的提问来源于stack exchange,提问作者John French
相关产品推荐
相关产品推荐

