如何从同一项目的另一个文件中包含模块?

通过本指南,我创建了一个Cargo项目。

src/main.rs

fn main() {
hello::print_hello();
}


mod hello {
pub fn print_hello() {
println!("Hello, world!");
}
}

我用它来运行

cargo build && cargo run

它编译时没有错误。现在我试图将主模块分成两个,但不知道如何包括来自另一个文件的模块。

我的项目树是这样的

├── src
├── hello.rs
└── main.rs

以及文件内容:

src/main.rs

use hello;


fn main() {
hello::print_hello();
}

src/hello.rs

mod hello {
pub fn print_hello() {
println!("Hello, world!");
}
}

当我用cargo build编译它时,我得到

error[E0432]: unresolved import `hello`
--> src/main.rs:1:5
|
1 | use hello;
|     ^^^^^ no `hello` external crate

我尝试按照编译器的建议修改main.rs为:

#![feature(globs)]


extern crate hello;


use hello::*;


fn main() {
hello::print_hello();
}

但这仍然没有多大帮助,现在我得到了这个:

error[E0463]: can't find crate for `hello`
--> src/main.rs:3:1
|
3 | extern crate hello;
| ^^^^^^^^^^^^^^^^^^^ can't find crate

是否有一个简单的例子说明如何将当前项目中的一个模块包含到项目的主文件中?

179808 次浏览

你的hello.rs文件中不需要mod hello。除crate根目录(main.rs用于可执行文件,lib.rs用于库)之外的任何文件中的代码都会自动在模块中进行命名空间。

要在你的main.rs中包含来自hello.rs的代码,使用mod hello;。它被展开到hello.rs中的代码(就像你之前那样)。你的文件结构保持不变,你的代码需要稍微改变:

main.rs:

mod hello;


fn main() {
hello::print_hello();
}

hello.rs:

pub fn print_hello() {
println!("Hello, world!");
}

如果你希望有嵌套模块…

2018年生锈

它是不再需要 来拥有文件mod.rs(尽管它仍然被支持)。惯用的替代方法是将文件命名为模块的名称:

$ tree src
src
├── main.rs
├── my
│   ├── inaccessible.rs
│   └── nested.rs
└── my.rs

main.rs

mod my;


fn main() {
my::function();
}

my.rs

pub mod nested; // if you need to include other modules


pub fn function() {
println!("called `my::function()`");
}

2015年生锈

你需要将一个mod.rs文件放在与你的模块同名的文件夹中。生锈的例子解释得更好。

$ tree src
src
├── main.rs
└── my
├── inaccessible.rs
├── mod.rs
└── nested.rs

main.rs

mod my;


fn main() {
my::function();
}

mod.rs

pub mod nested; // if you need to include other modules


pub fn function() {
println!("called `my::function()`");
}

我真的很喜欢园丁的反应。我一直在模块声明中使用这个建议。

./src
├── main.rs
├── other_utils
│   └── other_thing.rs
└── utils
└── thing.rs

文件main.rs

#[path = "utils/thing.rs"] mod thing;
#[path = "other_utils/other_thing.rs"] mod other_thing;


fn main() {
thing::foo();
other_thing::bar();
}

文件跑龙套/ thing.rs

pub fn foo() {
println!("foo");
}

文件other_utils / other_thing.rs

#[path = "../utils/thing.rs"] mod thing;


pub fn bar() {
println!("bar");
thing::foo();
}

在非main.rs(或lib.rs)文件中,如果你想从同一目录中的一个文件中包含,那么下面的代码可以工作。关键是在include中使用super::这个词。(这就是我在不使用path的情况下重写rodo的答案的方式。)

目录树:

src
├── main.rs
├── my.rs
└── my
├── a.rs
└── b.rs

b.rs中包含a.rs:

文件src /我/ a.rs

pub fn function() {
println!("src/my/a.rs/function()");
}

文件src /我/ b.rs

use super::b::function;


fn f2() {
function();
}

文件src / my.rs

mod a;
mod b;

文件src / main.rs

mod my;

截至2022年

├── src
├── main.rs
├── scripts
│   └── func.rs
└── scripts.rs

如果我想调用func.rs文件中的函数(在scripts文件夹中),我创建了一个所谓的“链接”;根目录中的文件与文件夹名称相同(链接文件名和文件夹名称不需要相同)。

文件脚本/ func.rs的内容:

pub fn sayHello(){
println!("Hello, World!");
}

scripts.rs文件中,我有:

pub(crate) mod func;

然后在我的main.rs文件中,我调用了sayHello()函数,如下所示:

mod scripts;
fn main() {
scripts::func::sayHello();
}

这是一个非常简单的方法来解决这个问题,你需要添加mod到主。Rs文件,因为它可以在整个文件树中访问