默认的浮点数类型是什么?

8

如果变量 a 指定为浮点型,可以使用 abs 函数。下面是运行的示例:

fn main() {
    let a = -1.0f64;
    println!("{:?}", a.abs());
}

它按预期打印1。但如果省略f64,则会在编译过程中抛出错误,如下例所示:

fn main() {
    let a = -1.0;
    println!("{:?}", a.abs());
}

这个版本报以下错误:

   Compiling playground v0.1.0 (file:///C:/git/Rust/playground)
src\main.rs:3:24: 3:29 error: no method named `abs` found for type `_` in the current scope
src\main.rs:3     println!("{:?}", a.abs());
                                     ^~~~~
note: in expansion of format_args!
<std macros>:2:25: 2:56 note: expansion site
<std macros>:1:1: 2:62 note: in expansion of print!
<std macros>:3:1: 3:54 note: expansion site
<std macros>:1:1: 3:58 note: in expansion of println!
src\main.rs:3:5: 3:31 note: expansion site
src\main.rs:3:24: 3:29 help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it:
src\main.rs:3:24: 3:29 help: candidate #1: use `core::num::Float`
error: aborting due to previous error
Could not compile `playground`.

To learn more, run the command again with --verbose.

这条信息表示a的类型为_。我猜测不能使用abs函数,因为不清楚a的具体类型是什么。这意味着在编译时没有定义类型吗?如果在Rust中没有声明特定的浮点类型,会使用哪种类型?

1个回答

6

RFC 212规定:

未定义类型的整数字面量将默认为i32,浮点数字面量将默认为f64

然而,在大多数情况下,一些限制条件会将推断类型约束为具体类型,例如将其传递给方法或将其放入结构体中。

这是不是意味着类型在编译时未定义?

类型将在代码实际编写之前始终被定义。但是,整数或浮点字面量的具体类型在类型上呈现了一种量子叠加状态,直到某些因素迫使它向一个方向偏转。如果没有任何限制条件,那么它将回退到默认值。

这就是最终使以下代码起作用的原因:

use std::{f32, f64};

fn main() {
    let a = -1.0;
    let b = -1.0;

    println!("{:?}", f32::abs(a));
    println!("{:?}", f64::abs(b));
}

如果变量是f32f64之一,那么可以选择其中一个。我不知道编译器内部的具体情况能否回答这个问题,但似乎默认类型的后备方案来得太迟,不能拯救你的代码。当方法查找正在进行时,它想要知道变量的类型以查找有效匹配项,但此时还不可用。


2
为什么 OP 的代码不能编译呢?(链接:https://play.rust-lang.org/?gist=10e4887dbc2efe616cd1&version=stable) - Matthieu M.
如果浮点数字面量默认为f64,则在上述代码中应使用f64abs函数。但是,由于错误消息中的_未指定类型。 - Holger
@MatthieuM。好问题。我不确定,但我的猜测是运算顺序不允许它。我已经编辑了我的当前猜测。 - Shepmaster
2
@Shepmaster:嗯,没有具体的规范很难说,但如果编译器没有及时执行回退操作,那么这听起来像是一个 bug... - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接