将整数添加到浮点时为什么会出错?

Jøê*_*èéñ 7 floating-point integer operators rust

我开始学习Rust.我试过这个程序:

fn main() {
     let a = 5;
     let b = 5.5;
     let k = a + b;
     println!("{}", k);
}
Run Code Online (Sandbox Code Playgroud)

它显示此错误:

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}`
Run Code Online (Sandbox Code Playgroud)

代码错了吗?

She*_*ter 19

技术上正确的答案是:因为没有人写impl Add<f64> for i32 {}.

厚脸皮的回答是:因为锈不希望你搬起石头砸自己的脚.

更长,可能更有用的答案是......

在计算机中,整数和浮点数都具有有限的范围,最终由我们用来表示它们的位数驱动.在Rust中,未受其他约束的整数的默认类型是a i32,并且未受其他约束的浮点的默认类型是a f64.

积分类型不允许您具有小数部分,浮点类型具有可以精确表示的有限数量的整数.如果Rust允许你添加这两种类型,那么就可以决定哪些数据不那么重要,这实际上并不是你希望系统编程语言做的事情!

以下是我可以看到的选项:

  1. 提出错误,迫使程序员选择他们需要的数据类型.
  2. 自动将两个数字转换为整数,丢弃任何潜在的小数值.
  3. 自动将两个数字转换为浮点数,不正确地表示较大的整数值.

在这些选择中,只有错误是合理的.

还有可能引入一种可以精确处理任意精度的类型.不幸的是,对于处理器来说,这些类型不再"便宜",因此您必须权衡性能.

如果程序员希望执行某些转换,那么您可以使用as以下方法转换值:

f64::from(a) + b;
Run Code Online (Sandbox Code Playgroud)
a + b as i32 
Run Code Online (Sandbox Code Playgroud)

Veedrac补充道:

[这个答案给出] From应该有效的印象,但Rust不做任何数字促销,即使促销无损.此外,0u32 + 0u64i32是无损促销,因为f64有52位尾数.

虽然这些类型的扩展促销确实是无损的,但它们会隐含地增加您的内存需求.例如,过去只需要32位的内容现在需要64位.除了内存要求之外,还有语义考虑因素.如果值应该只要求f64(0-255),那么它是没有意义的,可能是超出范围的值,以增加它.知道进行这种转换是恰当的,完全取决于程序员.

  • 虽然这个解释很好,但我认为这是误导.它给人的印象是"0u32 + 0u64"应该可以工作,但Rust不做*任何*数字促销,即使促销是无损的.另外,`i32`→`f64`是无损促销,因为`f64`有一个52位的尾数. (3认同)
  • @JøêGrèéñ我不确定我还能添加什么,我给出了Rust不做这些隐式转换的多个原因.C允许Rust没有的其他东西,例如解除引用NULL指针,但这并不意味着它应该是永久性的好主意.我想你的问题可以用另一种方式翻转:**为什么C允许在`int32_t`中添加`double`?** (3认同)
  • Rust 通常反对隐式转换。事情就是这样,但老实说我更喜欢这样。 (2认同)