如何在Rust中使用父模块导入?
如果您有如下目录结构:如何在Rust中使用父模块导入?,rust,Rust,如果您有如下目录结构: pub mod logging; use utils::logging; src/main.rs src/module1/blah.rs src/module1/blah2.rs src/utils/logging.rs 如何使用其他文件中的函数 从Rust教程中,听起来我应该能够做到: main.rs mod utils { pub mod logging; } mod module1 { pub mod blah; } fn main() { util
pub mod logging;
use utils::logging;
src/main.rs
src/module1/blah.rs
src/module1/blah2.rs
src/utils/logging.rs
如何使用其他文件中的函数
从Rust教程中,听起来我应该能够做到:
main.rs
mod utils { pub mod logging; }
mod module1 { pub mod blah; }
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
mod blah2;
pub fn doit() {
blah2::doit();
}
mod utils { pub mod logging; }
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
#[path="../utils/logging.rs"]
mod logging;
pub fn doit() {
logging::trace("Blah2 invoked");
}
logging.rs
mod utils { pub mod logging; }
mod module1 { pub mod blah; }
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
mod blah2;
pub fn doit() {
blah2::doit();
}
mod utils { pub mod logging; }
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
#[path="../utils/logging.rs"]
mod logging;
pub fn doit() {
logging::trace("Blah2 invoked");
}
blah.rs
mod utils { pub mod logging; }
mod module1 { pub mod blah; }
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
mod blah2;
pub fn doit() {
blah2::doit();
}
mod utils { pub mod logging; }
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
#[path="../utils/logging.rs"]
mod logging;
pub fn doit() {
logging::trace("Blah2 invoked");
}
blah2.rs
mod utils { pub mod logging; }
mod module1 { pub mod blah; }
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
mod blah2;
pub fn doit() {
blah2::doit();
}
mod utils { pub mod logging; }
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
#[path="../utils/logging.rs"]
mod logging;
pub fn doit() {
logging::trace("Blah2 invoked");
}
但是,这会产生一个错误:
错误[E0583]:找不到模块`日志记录的文件`
-->src/main.rs:1:21
|
1 | mod utils{pub mod logging;}
| ^^^^^^^
|
=帮助:将目录“src/utils”中的文件命名为logging.rs或logging/mod.rs
看来,沿着路径导入,即从main
到module1/blah.rs
起作用,导入同级,即从blah
导入blah2起作用,但从父范围导入不起作用
如果我使用神奇的#[path]
指令,我可以实现以下功能:
blah2.rs
mod utils { pub mod logging; }
mod module1 { pub mod blah; }
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
mod blah2;
pub fn doit() {
blah2::doit();
}
mod utils { pub mod logging; }
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
#[path="../utils/logging.rs"]
mod logging;
pub fn doit() {
logging::trace("Blah2 invoked");
}
我真的必须手动使用相对文件路径从父作用域级别导入内容吗?有没有更好的方法可以在铁锈中实现这一点
在Python中,本地作用域使用
from.blah import x
,但如果要访问绝对路径,可以使用from project.namespace.blah import x
如果创建名为mod.rs
的文件,则导入模块时,rustc
将查看该文件。我建议您创建文件src/utils/mod.rs
,并使其内容如下所示:
pub mod logging;
use utils::logging;
然后,在main.rs
中添加如下语句:
pub mod logging;
use utils::logging;
并称之为
logging::trace(...);
或者你也可以
use utils::logging::trace;
...
trace(...);
基本上,在
mod.rs
文件中声明您的模块,并在源文件中使用它。我假设您希望在顶层声明utils
和utils::logging
,只希望从module1::blah::blah2>中调用函数。模块的声明是通过mod
完成的,它将模块插入AST并定义其规范的foo::bar::baz
样式路径,与模块的正常交互(远离声明)是通过use
完成的
// main.rs
mod utils {
pub mod logging { // could be placed in utils/logging.rs
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
}
}
mod module1 {
pub mod blah { // in module1/blah.rs
mod blah2 { // in module1/blah2.rs
// *** this line is the key, to bring utils into scope ***
use crate::utils;
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
}
pub fn doit() {
blah2::doit();
}
}
}
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
我所做的唯一更改是使用板条箱::utils代码>行在blah2
(在Rust 2015中,您也可以使用使用utils
或使用::utils
)。有关use
工作原理的更多详细信息,请参见。这也是一个合理的参考,尤其是这两个小节:
另外,请注意,我将其全部内联编写,将foo/bar.rs
的内容直接放在mod foo{mod bar{}
中,将其更改为mod foo{mod bar;}
与可用的相关文件应该是相同的
(顺便说一句,println(“:{}\n”,msg)
打印两行;println!
已经包括一行(ln
是“行”),或者print!(“:{}\n,msg)
或者println!(“:{}”,msg)
只打印一行。)
要获得所需的确切结构并不惯用,您必须对blah2.rs的位置进行一次更改:
src
├── 梅因
├── 模块1
│ ├── 废话
│ │ └── blah2.rs
│ └── 废话
└── 乌提尔斯
└── 日志记录
梅因
utils/logging.rs
模块1/blah.rs
module1/blah/blah2.rs(唯一需要更改的文件)
我也要回答这个问题,对于任何发现这个问题并且(像我一样)完全被难以理解的答案弄糊涂的人来说
归结起来,我觉得有两件事在本教程中没有得到很好的解释:
modblah代码>语法为编译器导入文件。您必须在所有要编译的文件上使用此选项
- 与共享库一样,任何定义的本地模块都可以使用
use blah::blah导入当前范围代码>
一个典型的例子是:
src/main.rs
src/one/one.rs
src/two/two.rs
在这种情况下,您可以使用use
,将one.rs
中的代码从two.rs
中提取出来:
use two::two; // <-- Imports two::two into the local scope as 'two::'
pub fn bar() {
println!("one");
two::foo();
}
请注意,您可以使用blah/mod.rs
文件,通过放置类似one/mod.rs
的文件,在某种程度上缓解这种尴尬,因为mod x代码>尝试加载x.rs
和x/mod.rs
// one/mod.rs
pub mod one.rs
您可以将main.rs顶部的笨拙文件导入减少到:
use one::one::bar;
mod one; // <-- Loads one/mod.rs, which loads one/one.rs.
mod two; // <-- This is still awkward since we don't two, but unavoidable.
fn main() {
bar();
}
使用one::one::bar;
mod one;// 我意识到这是一篇很老的帖子,可能没有用到2018年。然而,这仍然是非常棘手的,我想帮助那些正在寻找的人
因为图片胜过千言万语,所以我将其简化为代码拆分
然后,正如您可能猜到的,它们都有一个空的pub fn some_function()
我们可以通过对main的更改进一步扩展这一点
对嵌套的_mod的附加更改
现在让我们返回并回答以下问题:
我们在mod_1中添加了blah1和blah2
我们添加了一个utils,其中包含另一个mod日志,调用一些fn。
我们的mod_1/mod.rs现在包含:
pub mod blah.rs
pub mod blah2.rs
我们创建了一个用于main的utils/mod.rs,其中包含:
pub mod logging
然后是一个名为logging/的目录,其中包含另一个mod.rs,我们可以将fns放入日志中进行导入
来源也在这里
还可以查看第7章中的libs示例和第14.3节,其中进一步扩展了Rust Book中的工作空间拆分。祝你好运 我想你误解了这个问题。从main.rs调用utils::logging已经可以工作了。我不是说尝试按名称导入模块,而是尝试从父作用域导入模块。也就是说,我试图从module1::blah内部使用utils::logging;utils在sc中