我正在翻阅《铁 rust 手册》的第二版,并决定try 制作classic 的摄氏到华氏转换器:

fn c_to_f(c: f32) -> f32 {
    return ( c * ( 9/5 ) ) + 32;
}

使用cargo build编译此文件将产生编译时错误:

error[E0277]: the trait bound `f32: std::ops::Mul<{integer}>` is not satisfied
 --> src/main.rs:2:12
  |
2 |     return (c * (9 / 5)) + 32;
  |            ^^^^^^^^^^^^^ the trait `std::ops::Mul<{integer}>` is not implemented for `f32`
  |
  = note: no implementation for `f32 * {integer}`

作为一名新的Rust程序员,我的解释是,我不能将浮点类型和整数类型相乘.我通过将所有常数设为浮点数来解决这个问题:

fn c_to_f(c: f32) -> f32 {
    return ( c * ( 9.0/5.0 ) ) + 32.0;
}

这让我有所保留.来自C/C++/Java/Python,令人惊讶的是,您不能简单地对不同类型的数字执行算术运算.像我在这里做的那样,简单地将它们转换为相同的类型是正确的吗?

推荐答案

TL;DR:as是在原始数字类型之间转换的最常见方式,但使用它需要思考.

fn c_to_f(c: f32) -> f32 {
    (c * (9 as f32 / 5 as f32)) + 32 as f32
}

但在本例中,更合理的做法是首先使用浮点文字:

fn c_to_f(c: f32) -> f32 {
    (c * (9. / 5.)) + 32.
}

问题是,做混合型算术有点复杂.

如果你用T乘以T,你通常希望得到T型的结果,至少是基本型的结果.

然而,混合类型时,存在一些困难:

  • 混合信号,
  • 混合精度.

例如,i8 * u32的理想结果是什么?可以包含全部i8u32值的最小类型是i64.这应该是结果吗?

再举一个例子,f32 * i32的理想结果是什么?可以包含全部f32i32值的最小类型是f64.这应该是结果吗?

我觉得有这样一个 idea 相当令人困惑.它也会影响性能(一旦矢量化,对f32的操作可能比对f64的操作快得多).

由于这些问题,Rust目前要求您明确:您希望计算采用哪种类型?哪种类型适合你的特殊情况?

然后使用as进行适当的转换,并考虑应用哪种舍入模式(从浮点转换为整数时为.round().ceil().floor().trunc()).

1 Adding, Subtracting and Dividing work in similar ways.

Rust相关问答推荐

将此字符串转换为由空格字符分隔的空格

PyReadonlyArray2到Vec T<>

为什么复印是豆荚的一个重要特征?

通过解引用将值移出Box(以及它被脱糖到什么地方)?

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

如何在Rust中将选项<;选项<;字符串>;转换为选项<;选项&;str>;?

无法实现整型类型的泛型FN

循环访问枚举中的不同集合

为什么特征默认没有调整大小?

是否可以在不直接重复的情况下为许多特定类型实现一个函数?

借来的价值生命周期 不够长,不确定为什么它仍然是借来的

在 Rust 中,是否可以定义一个需要实现类型的构造函数的对象安全特征?

将泛型中的 Box 转换为 rust 中的 Box

实现AsyncWrite到hyper Sender时发生生命周期错误

没有得到无法返回引用局部变量`queues`的值返回引用当前函数拥有的数据的值的重复逻辑

如何从 x86_64 Mac 构建 M1 Mac?

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

为什么在 rust 中删除 vec 之前应该删除元素

Rust 中的通用 From 实现

如何制作具有关联类型的特征的类型擦除版本?