我开始学习 Rust。我试过这个程序:
fn main() {
let a = 5;
let b = 5.5;
let k = a + b;
println!("{}", k);
}
它显示了这个错误:
error[E0277]: cannot add a float to an integer
--> src/main.rs:4:16
|
4 | let k = a + b;
| ^ no implementation for `{integer} + {float}`
|
= help: the trait `std::ops::Add<{float}>` is not implemented for `{integer}`
代码有错吗?
最佳答案
技术上正确的答案是:因为没有人写过 impl Add<f64> for i32 {}
.
厚颜无耻的回答是:因为 Rust 不希望你搬起石头砸自己的脚。
更长、可能更有用的答案是……
在计算机中,整数和 float 都有一个有限的范围,最终由我们用来表示它们的位数决定。在 Rust 中,不受其他约束的整数的默认类型是 i32
,并且不受其他约束的浮点的默认类型是 f64
.
整数类型不允许你有小数部分,而浮点类型 have a limited number of integers they can exactly represent .如果 Rust 让您添加这两种类型,它会替您决定哪些数据不太重要,这并不是您真正希望系统编程语言做的事情!
以下是我可以看到的选项:
- 引发错误,迫使程序员选择他们需要的数据类型。
- 自动将两个数字转换为整数,丢弃任何可能的小数值。
- 自动将两个数字都转换为 float ,不正确地表示较大的整数值。
在这些选择中,只有一个错误是合理的。
还有可能引入一种可以精确处理任意精度的类型。不幸的是,这些类型对于处理器运行来说不再“廉价”,因此您必须权衡性能。
如果程序员希望执行一些转换,那么您可以使用 as
转换值或 From
:
f64::from(a) + b;
a + b as i32
另见:
[this answer gives] the impression that
0u32 + 0u64
should work, but Rust doesn't do any numeric promotions, even if promotion would be lossless. Also,i32
→f64
is a lossless promotion, sincef64
has a 52-bit mantissa.
虽然这些类型的扩大促销确实是无损的,但它们会隐含地增加您的内存需求。例如,过去只占用 32 位的内容现在占用 64 位。除了内存要求之外,还有语义方面的考虑。如果一个值应该只需要 u8
(0-255),那么将它增加一个可能超出该范围的值是没有意义的。知道进行这样的转换是否合适完全取决于程序员。
使用 From
可以确保您只使用无损数字转换。
关于floating-point - 为什么将整数添加到 float 时会出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39677410/