我在 Rust 项目中的某个地方创建类似元组的结构时遇到了一个令人费解的错误。
错误
我把我的问题归结为以下片段:
mod parent {
pub struct X(u32);
mod child {
use crate::X;
fn f() {
let x = X(42);
}
}
}
use parent::X;
在我看来,此代码片段应该可以顺利编译。X
是公开的,并且其字段在 内可见parent
,因此其所有子级(包括child::f
)都应该能够访问它。但是,当我去编译该代码片段时,我得到了
error[E0423]: expected function, tuple struct or tuple variant, found struct `X`
--> src/main.rs:8:21
|
8 | let x = X(42);
| ^
For more information about this error, try `rustc --explain E0423`.
error: could not compile `playground` (bin "playground" test) due to 1 previous error
奇怪的是,错误消息提到编译器期望的是“元组变体”,但找到的X
却是。但是,X
是元组变体!
路径依赖
use
super::X
当我用 代替 时,问题就消失了crate::X
。
mod parent {
pub struct X(u32);
mod child {
use super::X;
fn f() {
let x = X(42);
}
}
}
use parent::X;
这对我来说更加令人困惑。为什么我的代码片段的正确性取决于我使用的特定路径use
X
?在我看来,无论我从哪里导入它,X
它都是。X
使用非元组结构
X
当我给出命名字段时,问题也消失了:
mod parent {
pub struct X {
x: u32,
}
mod child {
use crate::X;
fn f() {
let x = X { x: 42 };
}
}
}
use parent::X;
请注意,我在此代码片段中使用的use crate::X
与第一个代码片段中的一样!为什么此错误仅出现在类似元组的结构中?我非常困惑。我通常不会怀疑 Rust 编译器的正确性,但我不得不承认,今天我的信念受到了考验。
对于我可能遗漏的内容有什么见解吗?
这与#74139中的问题相同。
只有私有函数
X
(每个元组结构除了结构本身之外还隐式定义一个构造函数)被过滤掉,因此使用常规结构语法确实有效(对于两种结构类型):操场