按照 this guide,我创建了一个 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
是否有一个简单的示例说明如何将当前项目中的一个模块包含到项目的主文件中?
您不需要 hello.rs
文件中的 mod hello
。除 crate 根目录(main.rs
用于可执行文件,lib.rs
用于库)之外的任何文件中的代码都会在模块中自动命名空间。
要将来自 hello.rs
的代码包含在您的 main.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
是 no longer required(尽管它仍然受支持)。惯用的替代方法是将文件命名为模块的名称:
$ 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
文件放入与模块同名的文件夹中。 Rust by Example 更好地解释了它。
$ 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()`");
}
nested.rs
中使用来自 inaccessible.rs
的东西...我该怎么做?
#[path = "inaccessible.rs"]
和下一行:mod inaccessible;
mod inaccessible;
添加到 my/mod.rs
以使其成为 my
的子模块,然后通过相对路径 super::inaccessible::function()
从 nested.rs
访问兄弟模块。您在这里不需要 path
属性。
我真的很喜欢Gardener's response。我一直在为我的模块声明使用建议。
./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();
}
文件 utils/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();
}
fn
,并使用与其所在文件相同的名称。#[path = "./add_offer.rs"] mod _add_offer; pub use self::_add_offer::add_offer;
#[path = ...]
属性,当然新手也不应使用。每次执行 mod thing
,它创建一个新模块,即使 #[path = ...]
使它们指向同一个文件。这意味着在此示例中,声明了两个单独的 thing
模块:crate::thing
和 crate::other_thing::thing
。它在这里可能不是问题,因为它只包含一个函数,但是如果您定义类型,当编译器报告“预期的 mod1::A,找到 mod2::A”时,它可能会导致混淆。
mod.rs
文件的文件结构,您可以在 main.rs
中声明它们,如 mod other_utils { pub mod other_thing; }
和 mod utils { pub mod thing; }
。然后您可以像 crate::other_utils::other_thing
和 crate::utils::thing
一样访问它们。
在非 main.rs(或 lib.rs)文件中,如果您想从同一目录中的文件中包含,则下面的代码有效。关键是使用单词 super::
表示包含。 (这就是我在不使用 path
的情况下重写 answer of rodo 的方式。)
目录树:
src
├── main.rs
├── my.rs
└── my
├── a.rs
└── b.rs
要在 b.rs 中包含 a.rs:
文件 src/my/a.rs
pub fn function() {
println!("src/my/a.rs/function()");
}
文件 src/my/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 添加到 main.rs 文件中,以便在整个文件树中都可以访问它
mod
,这个答案没有添加现有答案没有的任何内容。
use
只是一个命名空间的东西,而mod
拉入文件。例如,您可以使用use
来调用print_hello
函数,而无需使用命名空间作为前缀