为什么我的Rust摄氏/华氏转换函数始终返回0、字符串比较不生效?
摄氏/华氏温度转换函数的修复说明
核心问题拆解
你的代码里不存在字符串比较的逻辑错误,哪怕你不使用String::from做对比,&str和字符串字面量的相等判断从一开始就是正常工作的,问题出在两个容易踩的Rust语法特性上:
- 块级作用域与变量遮蔽
所有用let声明的变量都只在当前代码块内有效。你在每个if分支里写的let result = xxx,本质是在if的块作用域里新建了一个和外层同名的局部变量,完全没有触碰函数开头定义的、初始值为0的外层result。不管if分支有没有命中,函数最后走到返回步骤的时候,返回的永远是外层那个初始为0的变量,这也是你修改了字符串比较逻辑也没效果的根本原因——你在分支里计算的所有结果,根本没被传递到外层的返回值中。
额外说明:函数开头定义的result是不可变绑定,就算你去掉分支里的let改成直接赋值,不把它改成可变绑定(加mut关键字)也会直接触发编译错误。 - 整数除法的截断行为
就算把变量遮蔽的问题解决了,整数运算会直接截断小数取整,根本拿不到正确的换算系数:- 摄氏转华氏公式里的
9/5,在i32类型的整数运算下结果是1,不是实际需要的1.8 - 华氏转摄氏公式里的
5/9,在i32类型的整数运算下结果是0,不是实际需要的约0.556
这种情况下哪怕赋值逻辑正确,算出来的结果也完全不对:100摄氏度会被算成132华氏,77华氏会被算成0摄氏度,和实际值偏差极大。
- 摄氏转华氏公式里的
修复后的可运行代码
fn main(){ println!("{}", convert_temp("c", 100)); // 水沸点转华氏:212 println!("{}", convert_temp("f", 77)); // 室温转摄氏:25 } fn convert_temp(from: &str, temp: i32) -> i32{ // 定义可变的返回值变量,支持后续赋值 let mut result = 0; if from == "c"{ // 直接给外层变量赋值,不重新声明同名变量;用浮点运算拿到正确的换算系数 // 最后四舍五入转回i32,保证返回值的精度符合日常使用习惯 result = ((temp as f64) * (9.0 / 5.0) + 32.0).round() as i32; } else if from == "f"{ result = (((temp - 32) as f64) * (5.0 / 9.0)).round() as i32; } result }
修复后运行效果
- 传入参数
"c", 100(标准大气压下的水沸点),会正确返回212(对应华氏温标下的沸点值) - 传入参数
"f", 77(日常舒适室温),会正确返回25(对应摄氏温标下的室温值)
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

