为什么使用 f32::consts::E 会给出错误 E0223 而 std::f32::consts::E 不会?

Why does using f32::consts::E give error E0223 but std::f32::consts::E does not?

如果我写:

let x = f32::consts::E;

我收到错误:

error[E0223]: ambiguous associated type
  --> src/main.rs:32:21
   |
32 |             let x = f32::consts::E;
   |                     ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<f32 as Trait>::consts`

但如果我改写:

let x = std::f32::consts::E;

然后一切都很好。错误消息令人困惑,因为据我了解, f32 是特定的具体类型而不是特征。我不确定为什么要使用一些特殊的特征语法。

编译器认为我在做什么,为什么我的修复有帮助?

What does the compiler think I'm doing

有一个名为 f32 模块 和一个名为 f32 类型 。默认类型随处可用,模块不可用

在没有额外导入的情况下,编译器最好将 f32::foo 理解为类型 f32 关联类型 ,但实际上并没有这样的类型。它假定关联类型来自特征,并建议您更明确地说明它是什么特征。

当您执行 std::f32 时,路径将模块带入作用域,然后可以找到嵌套模块 consts。您还可以这样做:

use std::f32;
let x = f32::consts::E;

任何类型都可能发生这种情况,但通常类型和模块使用不同的命名风格(UpperCamelCase vs snake_case):

struct my_type;

mod other {
    pub mod my_type {
        pub mod consts {
            pub const ZERO: i32 = 0;
        }
    }
}

fn example() {
    my_type::consts::ZERO;
}
error[E0223]: ambiguous associated type
  --> src/lib.rs:12:5
   |
12 |     my_type::consts::ZERO;
   |     ^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<my_type as Trait>::consts`

碰巧原语全部使用小写。

这里有一些代码(用处可疑)显示了关联类型实际上是如何发生的:

struct Consts;

impl Consts {
    const E: char = 'e';
}

trait Example {
    type consts;
}

impl Example for f32 {
    type consts = Consts;
}

fn example() {
    <f32 as Example>::consts::E;
}