Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Rust中使用父模块导入?_Rust - Fatal编程技术网

如何在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中