使用相互引用的结构在单个文件中很常见,但是当我将结构分成两个文件时,我收到错误。
mod_1.rs
mod mod_2;
use mod_2::Haha;
pub struct Hehe {
obj: Haha,
}
fn main() {
Hehe(Haha);
}
mod_2.rs
mod mod_1;
use mod_1::Hehe;
pub struct Haha {
obj: Hehe,
}
fn main() {
Haha(Hehe);
}
这会产生错误。编译mod_1.rs
:
error: cannot declare a new module at this location
--> mod_2.rs:1:5
|
1 | mod mod_1;
| ^^^^^
|
note: maybe move this module `mod_2` to its own directory via `mod_2/mod.rs`
--> mod_2.rs:1:5
|
1 | mod mod_1;
| ^^^^^
note: ... or maybe `use` the module `mod_1` instead of possibly redeclaring it
--> mod_2.rs:1:5
|
1 | mod mod_1;
| ^^^^^
编译mod_2.rs
:
error: cannot declare a new module at this location
--> mod_1.rs:1:5
|
1 | mod mod_2;
| ^^^^^
|
note: maybe move this module `mod_1` to its own directory via `mod_1/mod.rs`
--> mod_1.rs:1:5
|
1 | mod mod_2;
| ^^^^^
note: ... or maybe `use` the module `mod_2` instead of possibly redeclaring it
--> mod_1.rs:1:5
|
1 | mod mod_2;
| ^^^^^
在 mod_1.rs
我使用 mod_2.rs
和 mod_2.rs
中的内容,我使用< strong> mod_1.rs
的事情,所以我想找到摆脱循环参考模块问题的方法。
Trying to get Rust to load files是一个类似但不同的问题。
答案 0 :(得分:6)
这是对Rust模块系统的常见误解。基本上,有两个步骤:
您必须构建模块树。这意味着此模块树中没有循环,并且节点之间存在明确的父子关系。这一步只是告诉Rust要加载哪些文件,并且与不同模块中某些符号的用法无关。
您现在可以通过其路径引用模块树中的每个符号(其中每个模块和最终符号名称由::
分隔,例如std::io::read
)。为了避免每次都写出完整路径,您可以使用use
声明来通过简单名称引用特定符号。
您可以在in the Rust book chapter上阅读更多内容。
同样,为了避免混淆:为了使用模块中的符号,您不要必须在模块中编写mod my_module;
!对于项目的每个非根模块,整个项目中只有一个行mod said_module;
(根模块根本没有这样的行)。只有一次!
关于您的示例:您首先通过mod_1.rs
汇编了rustc mod_1.rs
。这意味着mod_1
是您案例中的根模块。如上所述,根模块根本不需要通过mod
声明,但是所有其他模块需要正好声明一次。这意味着mod mod_2;
中的mod_1.rs
完全正确,但mod mod_1;
中的mod_2.rs
不正确。编译器甚至建议做正确的事情:
note: ... or maybe `use` the module `mod_2` instead of possibly redeclaring it
您已经use
了它,因此您只需删除行mod mod_1;
并解决此错误。
但是,我认为你仍在思考模块系统。如上所述,您首先需要设计一个或多或少固定的模块树,这意味着您有一个固定的根模块。无论您传递给rustc
的是根模块,使用不同模块作为根模块都没有意义。在您的项目中应该有一个固定的根模块。如上所述,这可能是mod_1
。但是,对于库,lib
称为可执行文件,main
通常更为惯用。
再次:首先,在一张纸上绘制模块树。暂时考虑这个问题,然后你可以适当地创建文件和mod
声明。
最后一件事:即使在修复模块系统时,您的示例也无法正常工作,因为Haha
和Hehe
是无限大小的类型。结构的字段直接放入结构的内存布局中(不像Java那样装箱!)。因此,如果您手动添加一个间接层(如装箱字段),则不能在结构定义中使用除之外的循环。有关此问题,请阅读this excellent explanation。