Rust中match语句通过函数return与循环break返回值的差异问题
Rust中match语句通过函数return与循环break返回值的差异问题
嘿,我来帮你拆解这个问题的根源~
你遇到的编译错误,核心原因是Rust里表达式和语句的区别,以及循环与函数返回值的不同逻辑:
先看错误的直接原因
你的invalid_input函数里,match块的结尾加了一个分号:
match input.trim().parse(){ Ok(num) => return num, Err(_) => invalid_input() }; // 这里的分号是罪魁祸首!
在Rust中,带分号的是语句,语句的返回值是单元类型();不带分号的是表达式,表达式会返回自身的计算结果。
虽然你在Ok(num)分支里用了return num提前返回,但当走到Err(_)分支时,调用invalid_input()递归处理,递归返回的f64会成为match表达式的结果——但你加了分号,把这个match表达式变成了语句,相当于丢弃了这个返回值。函数体执行到这里后,没有其他返回表达式,就会默认返回(),这和你函数声明的返回类型f64不匹配,所以编译器报错。
再对比循环和函数的返回逻辑
- loop循环的情况:
loop本身是一个表达式,break num会直接把num作为整个loop表达式的返回值,所以你能把loop的结果赋值给inputed_fahrenheit,类型完全匹配。 - 函数的情况:函数的返回值要么靠
return提前返回,要么靠函数体的最后一个无分号的表达式作为返回值。你的递归函数里,去掉match后面的分号,match表达式的结果就会成为函数的返回值:当Err(_)时,递归调用invalid_input()的返回值会被直接返回,完美匹配f64类型。
修正后的递归函数代码
把match后面的分号去掉就行,我还帮你优化了main函数的逻辑,让代码更简洁:
use std::io; fn main() { println!("Please input a temperature in Fehrenheit: "); let inputed_fahrenheit: f64 = invalid_input(); let converted_temperature: f64 = convert_f_temperature_to_c(inputed_fahrenheit); println!("{converted_temperature}"); } fn invalid_input() -> f64 { println!("Please input valid 64-bit floating point number."); let mut input = String::new(); io::stdin() .read_line(&mut input) .expect("Failed to read lines"); match input.trim().parse() { Ok(num) => num, // 这里甚至可以去掉return,直接用表达式返回 Err(_) => invalid_input() } // 移除了这里的分号! } fn convert_f_temperature_to_c(f_temp: f64) -> f64 { ((f_temp - 32.0) * 5.0) / 9.0 }
额外小提示
递归写法虽然有趣,但要注意:如果用户连续输入错误很多次,递归深度过大可能会导致栈溢出(不过日常使用中这种情况几乎不会发生),迭代式的循环写法在鲁棒性上会更稳妥哦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

