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

ave*_*ave 91 rust

按照本指南,我创建了一个货运项目

SRC/main.rs

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

mod hello {
    pub fn print_hello() {
        println!("Hello, world!");
    }
}
Run Code Online (Sandbox Code Playgroud)

我运行使用

cargo build && cargo run
Run Code Online (Sandbox Code Playgroud)

它编译没有错误.现在我正在尝试将主模块分成两部分,但无法弄清楚如何从另一个文件中包含一个模块.

我的项目树看起来像这样

??? src
    ??? hello.rs
    ??? main.rs
Run Code Online (Sandbox Code Playgroud)

和文件的内容:

SRC/main.rs

use hello;

fn main() {
    hello::print_hello();
}
Run Code Online (Sandbox Code Playgroud)

SRC/hello.rs

mod hello {
    pub fn print_hello() {
        println!("Hello, world!");
    }
}
Run Code Online (Sandbox Code Playgroud)

当我编译它src/main.rs,我得到

error[E0432]: unresolved import `hello`
 --> src/main.rs:1:5
  |
1 | use hello;
  |     ^^^^^ no `hello` external crate
Run Code Online (Sandbox Code Playgroud)

我试图遵循编译器的建议并修改main.rs

#![feature(globs)]

extern crate hello;

use hello::*;

fn main() {
    hello::print_hello();
}
Run Code Online (Sandbox Code Playgroud)

但这仍然没有多大帮助,现在我明白了

error[E0463]: can't find crate for `hello`
 --> src/main.rs:3:1
  |
3 | extern crate hello;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate
Run Code Online (Sandbox Code Playgroud)

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

另外,我每晚运行Rust 0.13.0和每晚0.0.1的货物.

Ren*_*non 180

您不需要mod hello在您的hello.rs文件上.任何文件的代码,但crate根(main.rs对于可执行文件,lib.rs对于库)在模块上自动命名.

要包含您的代码,hello.rsmain.rs使用mod hello;.它会扩展到打开的代码hello.rs(与之前完全一样).您的文件结构保持不变,您的代码需要稍微更改:

main.rs:

mod hello;

fn main() {
    hello::print_hello();
}
Run Code Online (Sandbox Code Playgroud)

hello.rs:

pub fn print_hello() {
    println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)

  • @ChristianSchmitt不,他们是不同的东西.`use`只是一个命名空间的东西,而`mod`拉入文件.例如,您可以使用`use`来调用`print_hello`函数,而不必使用命名空间作为前缀 (10认同)
  • 迟到的问题,如果我用 use hello 而不是 mod hello 来指定它,它也不会起作用吗?! (6认同)

小智 25

我真的很喜欢园丁的回应。我一直在使用我的模块声明的建议。如果有技术问题,请有人插话。

./src
??? main.rs
??? other_utils
?   ??? other_thing.rs
??? utils
    ??? thing.rs
Run Code Online (Sandbox Code Playgroud)

主文件

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

fn main() {
  thing::foo();
  other_thing::bar();
}
Run Code Online (Sandbox Code Playgroud)

实用程序/东西.rs

pub fn foo() {
  println!("foo");
}
Run Code Online (Sandbox Code Playgroud)

other_utils/other_thing.rs

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

pub fn bar() {
  println!("bar");
  thing::foo();
}
Run Code Online (Sandbox Code Playgroud)

  • 作为 Rust 新手,如此简单的概念(导入其他代码)需要如此多的研究,这有点令人不安。另外 #[path..] 语法很丑陋 (12认同)
  • 这是误导性的,除非在晦涩的情况下,否则不应使用“#[path = ...]”属性,并且新手当然不应该使用该属性。每次执行“mod thing”时,它都会“创建一个新模块”,即使“#[path = ...]”使它们指向同一个文件。这意味着在此示例中,声明了两个单独的“thing”模块:“crate::thing”和“crate::other_thing::thing”。它在这里可能不是问题,因为它只包含一个函数,但如果您定义类型,当编译器报告“expected mod1::A,found mod2::A”时,可能会导致混乱。 (6认同)
  • 请使用标准机制。如果你确实想要这个文件结构而不需要中间的`mod.rs`文件,你可以在`main.rs`中声明它们,比如`mod other_utils { pub mod other_thing; }` 和 `mod utils { pub mod thing; }`。然后你可以像 `crate::other_utils::other_thing` 和 `crate::utils::thing` 一样访问它们。 (4认同)

小智 11

您需要mod.rs文件夹中的文件.Rust by Example更好地解释了它.

$ tree .
.
|-- my
|   |-- inaccessible.rs
|   |-- mod.rs
|   |-- nested.rs
`-- split.rs
Run Code Online (Sandbox Code Playgroud)

main.rs

mod my;

fn main() {
    my::function();
}
Run Code Online (Sandbox Code Playgroud)

mod.rs

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

pub fn function() {
    println!("called `my::function()`");
}
Run Code Online (Sandbox Code Playgroud)

  • 假设我想在“ nested.rs”中使用“ inaccessible.rs”中的东西...我该怎么做? (3认同)
  • @HemanGandhi 将“mod inaccessible;”添加到“my/mod.rs”,使其成为“my”的子模块,然后通过相对路径“super::inaccessible::function()”从“nested.rs”访问同级模块。这里不需要 `path` 属性。 (3认同)
  • 要从 main.rs 以外的文件访问同级 .rs 文件,请使用路径属性。因此,在nested.rs的顶部添加以下内容:`#[path = "inaccessible.rs"]`并在下一行:`mod inaccessible;` (2认同)

kei*_*fly 11

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

\n

目录树:

\n
src\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.rs\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 my.rs\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 a.rs\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 b.rs\n
Run Code Online (Sandbox Code Playgroud)\n

a.rs包含在b.rs中:

\n

文件src/my/a.rs

\n
pub fn function() {\n    println!("src/my/a.rs/function()");\n}\n
Run Code Online (Sandbox Code Playgroud)\n

文件src/my/b.rs

\n
use super::b::function;\n\nfn f2() {\n    function();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

文件src/my.rs

\n
mod a;\nmod b;\n
Run Code Online (Sandbox Code Playgroud)\n

文件src/main.rs

\n
mod my;\n
Run Code Online (Sandbox Code Playgroud)\n


Jul*_*kar 7

截至 2022 年

\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.rs\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 scripts\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 func.rs\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 scripts.rs\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

文件script/func.rs的内容:

\n
pub fn sayHello(){\n    println!("Hello, World!");\n}\n
Run Code Online (Sandbox Code Playgroud)\n

script.rs文件中我有:

\n

pub(crate) mod func;

\n

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

\n
mod scripts;\nfn main() {\n    scripts::func::sayHello();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 回复“截至 2022 年”*:您能否[说明](https://stackoverflow.com/posts/71943939/edit) 内容的版本(编译器、约定、文档/规范等)?也许还测试了哪个系统(包括版本)。(但是***没有***“编辑:”、“更新:”或类似内容 - 答案应该看起来就像今天写的一样。) (3认同)

Ral*_* L. 5

这个问题有两种情况,到目前为止我看到的答案只涵盖一种情况:当你有 a main.rs、 anda.rs和 a b.rs,都在同一个目录中,但你想使用 froma.rsb.rsin的函数main.rs,但是我还没有看到有人介绍过相反的情况,所以我就在这里做一下。

给定main.rsa.rs、 和b.rs全部位于同一目录中,并且您希望在 A 中使用 B 中的函数,或在 B 中使用 A 中的函数

main.rs

mod a;
mod b;

use crate::a::*;
use crate::b::*;

// To call a function from a.rs, do:
a::my_function_from_a();
Run Code Online (Sandbox Code Playgroud)

a.rs

use crate::b;

// To call a function from b.rs, do:
super::b::my_function_from_b();

Run Code Online (Sandbox Code Playgroud)

关键字superina.rs就是神奇发生的地方。令人烦恼的是,该行为与 Ruby 版本不同super

如果你不使用 super 关键字,你会得到可怕的:[E0433] use of undeclared crate or module