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

Posted

技术标签:

【中文标题】如何包含来自同一项目的另一个文件的模块?【英文标题】:How to include a module from another file from the same project? 【发布时间】:2014-12-10 21:39:59 【问题描述】:

通过关注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

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

【问题讨论】:

Rust basic imports (includes)的可能重复 相关***.com/questions/22596920/… 【参考方案1】:

您的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!");

【讨论】:

如果我用 use hello 而不是 mod hello 指定它,它是否也可以工作?! @ChristianSchmitt 不,它们是不同的东西。 use 只是一个命名空间的东西,而 mod 拉入文件。例如,您可以使用use 来调用print_hello 函数,而无需使用命名空间前缀 @RenatoZannon 这应该是另一个问题!【参考方案2】:

如果您希望有嵌套模块...

生锈 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 的东西......我该怎么做? 要从 main.rs 以外的文件访问同级 .rs 文件,请使用 path 属性。因此,在nested.rs 的顶部,添加以下内容:#[path = "inaccessible.rs"] 和下一行:mod inaccessible; @Gandhi 见The path attribute @HemanGandhi 将mod inaccessible; 添加到my/mod.rs 使其成为my 的子模块,然后通过相对路径super::inaccessible::function()nested.rs 访问兄弟模块。这里不需要path 属性。【参考方案3】:

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

./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; 作为一个 Rust 新手,这么简单的概念(导入其他代码)需要这么多研究,这有点令人不安。加上 #[path..] 语法很丑 这是误导性的,#[path = ...] 属性不应使用,除非在晦涩难懂的情况下使用,当然新手也不应使用。每次您执行mod thing 时,它创建一个新模块,即使#[path = ...] 使它们指向同一个文件。这意味着在此示例中,声明了两个单独的 thing 模块:crate::thingcrate::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_thingcrate::utils::thing一样访问它们。【参考方案4】:

在非 main.rs(或 lib.rs)文件中,如果您想从同一目录中的文件中包含,则下面的代码有效。关键是使用单词super:: 作为包含。 (这就是我在不使用path的情况下重写@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;

【讨论】:

以上是关于如何包含来自同一项目的另一个文件的模块?的主要内容,如果未能解决你的问题,请参考以下文章

如何从同一项目中的另一个类访问主类中的变量? [复制]

如何“包含”来自不同模块的 Thrift 文件?

Python:从项目层次结构中同一级别的另一个目录导入模块

我们如何在 Nuxt?Vuejs 项目中仅包含来自 lodash 的必需模块?

从当前项目中的另一个模块启动 MainActivity

无法将 Java 项目中的类文件导入同一项目中的另一个类文件