我开始学习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}`

代码错了吗?

推荐答案

technically correct答案是:因为没有人写过impl Add<f64> for i32 {}.

答案是:因为Rust不想让你射中自己的脚.

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

在计算机中,整数和浮点数都有一个有限的范围,最终取决于我们用来表示它们的位数.在Rust中,未受其他约束的整数的默认类型为i32,未受其他约束的浮点的默认类型为f64.

整数类型不允许有小数部分,浮点类型为have a limited number of integers they can exactly represent.如果Rust允许您添加这两种类型,它将为您做出关于which piece of data was less important的决定,这并不是您真正希望系统编程语言做的事情!

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

  1. 引发错误,迫使程序员 Select 所需的数据类型.
  2. 自动将两个数字转换为整数,丢弃任何可能的小数.
  3. 自动将两个数字转换为浮点,不正确地表示较大的整数值.

在这些 Select 中,只有一个错误是合理的.

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

如果程序员希望执行一些转换,则可以使用asFrom来转换值:

f64::from(a) + b;
a + b as i32 

另见:


Veedrac adds:

[这个答案给人的印象是0u32 + 0u64应该有效,但Rust不会进行任何数字促销,即使促销是无损的.还有i32f64是无损促销,因为f64有52位尾数.

虽然这些类型的扩大促销确实是无损的,但它们会隐含地增加你的记忆需求.例如,过go 只需要32位的东西现在需要64位.除了内存需求,还有语义方面的考虑.如果值should只需要u8(0-255),那么将其增加一个可能超出该范围的值是没有意义的.要知道进行这样的转换是合适的,这完全取决于程序员.

使用From可以确保只使用无损数字转换.

Rust相关问答推荐

如何在Rust中在屏幕中间打印内容?

常量泛型和类型枚举箱有重叠的用途吗?

rust 蚀生命周期 行为

铁 rust 干线无法使用PowerShell获取环境变量

如何将像烫手山芋一样不透明的值从一个Enum构造函数移动到下一个构造函数?

如何为rust trait边界指定多种可能性

如何实现Serde::Ser::Error的调试

为什么Deref类特征不构成?

为什么 `Deref` 没有在 `Cell` 上实现?

Cargo.toml:如何有条件地启用依赖项功能?

将特征与具有生命周期的关联类型一起使用时的生命周期方差问题

RUST 中的读写器锁定模式

信号量释放后 Rust 输出挂起线程

仅在使用 &mut 或线程时borrow 的数据在闭包之外转义?

decltype、dyn、impl traits,重构时如何声明函数的返回类型

当你删除一个存在于堆栈中的值时,为什么 rust 不会抱怨

将原始可变指针传递给 C FFI 后出现意外值

是否可以在 Rust 中的特定字符上实现特征?

在 Rust 中返回对枚举变体的引用是个好主意吗?

在传输不可复制的值时实现就地枚举修改