![](/img/trans.png)
[英]How do I import a module from the same directory explicitly in Python 2?
[英]How to include files from same directory in a module using Cargo/Rust?
我有一个 Cargo 项目,由同一目录中的三个文件组成: main.rs
、 mod1.rs
和mod2.rs
。
我想将函数从mod2.rs
导入到mod1.rs
,就像我将函数从mod1.rs
导入到main.rs
。
我已经阅读了所需的文件结构,但我不明白 - 将所有导入的文件命名为mod
会导致编辑器中的轻微混乱,而且这只会使项目层次结构复杂化。
有没有办法像在 Python 或 C++ 中那样独立于目录结构导入/包含文件?
主.rs:
mod mod1; // Works
fn main() {
println!("Hello, world!");
mod1::mod1fn();
}
mod1.rs:
mod mod2; // Fails
pub fn mod1fn() {
println!("1");
mod2::mod2fn();
}
mod2.rs:
pub fn mod2fn() {
println!("2");
}
构建结果:
error: cannot declare a new module at this location
--> src\mod1.rs:1:5
|
1 | mod mod2;
| ^^^^
|
note: maybe move this module `src` to its own directory via `src/mod.rs`
--> src\mod1.rs:1:5
|
1 | mod mod2;
| ^^^^
note: ... or maybe `use` the module `mod2` instead of possibly redeclaring it
--> src\mod1.rs:1:5
|
1 | mod mod2;
| ^^^^
我无法use
它,因为它在任何地方都不作为模块存在,而且我不想修改目录结构。
所有顶级模块声明都应该放在main.rs
,如下所示:
mod mod1;
mod mod2;
fn main() {
println!("Hello, world!");
mod1::mod1fn();
}
然后你可以在mod1
use crate::mod2
:
use crate::mod2;
pub fn mod1fn() {
println!("1");
mod2::mod2fn();
}
如果您还没有阅读Rust 书的新版本中关于模块的章节,我建议您阅读 - 它们对于不熟悉该语言的人来说可能有点混乱。
如果你不希望你的mod
语句都在你的主文件中(例如:在main.rs
你不会在某个模块中使用一些公共成员,在这个例子中它是mod2
)你可以执行以下操作:
以这种方式构建您的src
:
main.rs
my_module:
mod.rs
mod1.rs
mod2.rs
那么你可以只修改mod my_module
并use my_module::mod1
,如下所示:
主.rs:
mod my_module;
use my_module::mod1;
fn main() {
println!("Hello, world!");
mod1::mod1fn();
}
my_module/mod.rs
pub mod mod1;
pub mod mod2;
my_module/mod1.rs
use super::mod2;
pub fn mod1fn() {
println!("1");
mod2::mod2fn();
}
每个文件都是一个模块,如果不创建新的嵌套模块,就不能导入另一个文件。
正如@giuliano-oliveira 的回答所建议的那样。
添加pub mod mod1; pub mod mod2;
pub mod mod1; pub mod mod2;
在src/lib.rs
/ src/main.rs
/ src/foo/mod.rs
。
#[path]
主文件
#[path = "./mod2.rs"]
mod mod2;
fn run() { mod2::mod2fn() }
对于新的 Rust 开发人员来说,这是一个常见的陷阱,这是可以理解的。
混淆的原因来自于mod X
对同一文件夹中文件的行为不一致。 您可以在lib.rs
使用mod X
,这似乎会导入与其相邻的文件,但您不能在mod1.rs
或mod2.rs
执行相同mod2.rs
。
每个文件的代码都属于一个模块。 文件模块的完整路径(例如foo::bar::baz
)而不是文件的位置,决定了它如何解析mod X
。 你可以把它想象成每个模块都有一个固定的精神家园,但它可能在层次结构中定义了更src/lib.rs
成员(例如src/lib.rs
可能包含: mod foo { mod bar { pub fn hello() {} } }
- 虽然你不能在lib.rs
单独使用mod foo;
)。
在main.rs
,您位于顶级模块crate
。
mod mod1;
创建一个新的模块mod1
,并增加内容./mod1.ts
该模块。
所以./mod1.rs
所有代码都在crate::mod1
模块中。
当您在./mod1.rs
内调用use mod2
,它会看到它在crate::mod1
,其精神主目录为src/mod1
,并查找:
src/mod1/mod2.rs
src/mod1/mod2/mod.rs
复杂性来自允许模块是目录和文件,而不是强制每个模块是它自己的目录(可能试图避免 Java 文件夹结构),这将消除歧义。
要记住的关键是lib.rs
和mod.rs
是特殊文件,它们的行为与目录中的其他文件不同。
它们将始终位于父文件夹路径所描述的模块中(例如src/foo/bar/mod.rs
= foo::bar
),而所有其他文件属于它们自己的模块( src/foo/bar/baz.rs
= foo::bar::baz
)。
Rust 对此有一些看法。
不再推荐使用mod.rs
,这很好,因为它具有来自其兄弟姐妹的这种特殊行为。 但是lib.rs
和main.rs
仍然很特别。
如果您想将测试与代码( foo.rs
+ foo_test.rs
)放在一起,建议您不要。 我不喜欢这样,所以我使用了上面的path
,我认为这对测试来说很好,因为它们没有被导出到任何地方。 必须在上面的模块中声明测试感觉是错误的,我也不喜欢必须使用foo/test.rs
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.