Rust之包,箱和模块管理(五):将模块分成不同的文件

开发环境

  • Windows 10
  • Rust 1.64.0

 

  •   VS Code 1.71.2 

Rust之包,箱和模块管理(五):将模块分成不同的文件_第1张图片

项目工程

这里继续沿用上次工程rust-demo

 将模块分成不同的文件

到目前为止,本章中的所有例子都在一个文件中定义了多个模块。当模块变大时,您可能希望将它们的定义移动到一个单独的文件中,以使代码更容易导航。

例如,让我们从之前的例子中有多个餐馆模块的代码开始。我们将把模块提取到文件中,而不是把所有模块都定义在板条箱根文件中。在这种情况下,板条箱根文件是src/lib.rs,但是这个过程也适用于箱crate根文件是src/main.rs的二进制箱crate。

首先,我们将把front_of_house模块提取到它自己的文件中。删除front_of_house模块的花括号内的代码,只保留mod front _ of _ house声明,以便src/lib.rs包含之前示例所示的代码。注意,在我们下述示例中的src/front_of_house.rs文件之前,这不会被编译。

文件名:src/lib.rs

mod front_of_house;               // 保留front_of_house模块声明

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

接下来,将花括号中的代码放到名为src/front_of_house.rs的新文件中,如下所示。编译器知道在这个文件中查找,因为它在名为front_of_house的箱crate根目录中发现了模块声明。

文件名:src/front_of_house.rs

pub mod hosting {
    pub fn add_to_waitlist() {}
}

请注意,您只需要在模块树中使用一次mod声明来加载文件。一旦编译器知道文件是项目的一部分(并且因为mod语句的位置而知道代码在模块树中的位置),项目中的其他文件就应该使用声明它的路径来引用加载的文件的代码,如之前的章节所述。换句话说,mod不是你可能在其他编程语言中见过的“包含”操作。

接下来,我们将把hosting模块提取到它自己的文件中。这个过程有点不同,因为hostingfront_of_house的子模块,而不是根模块的子模块。我们将把这个文件放在一个新的目录中,这个目录将以它在模块树中的祖先命名,在这个例子中是src/front_of_house/

为了开始移动hosting,我们将src/front_of_house.rs更改为只包含hosting模块的声明:

文件名:src/front_of_house.rs

pub mod hosting;             // 声明hosting模块

然后,我们创建一个src/front_of_house目录和一个hosting.rs文件来包含在hosting模块中所做的定义:

文件名:src/front_of_house/hosting.rs

pub fn add_to_waitlist() {}

如果我们将hosting.rs放在src目录中,编译器会希望hosting.rs代码位于在crate root中声明的hosting模块中,而不是声明为front_of_house模块的子模块。编译器检查哪些文件有哪些模块代码的规则意味着目录和文件与模块树更加匹配。

备用文件路径

到目前为止,我们已经介绍了Rust编译器使用的最惯用的文件路径,但是Rust也支持一种更老的文件路径。对于在机箱根目录中声明的名为front_of_house的模块,编译器将在以下位置查找该模块的代码:

  • src/front_of_house.rs(我们涵盖的内容)
  • src/front_of_house/mod.rs(旧样式,仍支持路径)

对于名为hosting的模块,它是front_of_house的子模块,编译器将在以下位置查找该模块的代码:

  • src/front_of_house/hosting.rs(我们涵盖的内容)
  • src/front_of_house/hosting/mod.rs(旧样式,仍支持路径)

如果您对同一个模块使用两种风格,您将得到一个编译器错误。允许在同一个项目的不同模块中混合使用这两种风格,但是可能会让浏览您的项目的人感到困惑。

使用名为mod.rs的文件的风格的主要缺点是,您的项目最终可能会有许多名为mod.rs的文件,当您同时在编辑器中打开它们时,会感到困惑。

我们已经将每个模块的代码移动到一个单独的文件中,模块树保持不变。eat_at_restaurant中的函数调用无需任何修改即可工作,即使定义位于不同的文件中。这种技术允许您在模块变大时将它们移动到新文件中。

注意src/lib.rs中的pub use crate::front_of_house::hosting语句也没有改变,use也没有对作为箱crate的一部分编译的文件产生任何影响。mod关键字声明模块,Rust在与该模块同名的文件中查找进入该模块的代码。

总结

Rust允许您将一个包拆分成多个箱crate,并将一个箱crate拆分成多个模块,这样您就可以从一个模块中引用另一个模块中定义的项目。您可以通过指定绝对或相对路径来实现这一点。可以用use语句将这些路径带入范围,这样就可以在该范围内多次使用该项时使用较短的路径。默认情况下,模块代码是私有的,但是可以通过添加pub关键字将定义公开

本章重点

  • mod关键字及使用方法
  • 通过创建文件调整模块结构
  • 模块名尽量使用公有pub
  • 创建的文件名和模块名尽量一致
  • 确保代码目录结构一致

你可能感兴趣的:(Rust,rust,开发语言,后端)