首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Rust学习】16_抽离模块到独立的文件

【Rust学习】16_抽离模块到独立的文件

原创
作者头像
思索
发布2024-11-21 08:34:40
发布2024-11-21 08:34:40
2140
举报
文章被收录于专栏:Rust入门笔记Rust入门笔记

前言

到目前为止,本章中的所有示例都在一个文件中定义了多个模块。当模块变大时,您可能希望将它们的定义移动到单独的文件中,以便更轻松地浏览代码。

内容

现在让我们先把餐厅模块的代码进行梳理。我们将把模块提取到文件中,而不是在crate根文件中定义所有模块。在这种情况下,crate根文件是src/lib.rs,但此过程也适用于二进制crate,其crate根文件是src/main.rs,为了和之前的进行区别,我们这里新建一个项目。

代码语言:shell
复制
$ cargo new restaurant_pro --lib

首先,我们将把front_of_house模块提取到它自己的文件中。移除front_of_house模块花括号内的代码,只留下mod front_of_house;声明,如下所示:

代码语言:rust
复制
mod front_of_house;

pub use crate::front_of_house::hosting;

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

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

代码语言:rust
复制
pub mod hosting {
    pub fn add_to_waitlist() {}
}

请注意,你只需要在模块树中使用 mod 声明加载一次文件。一旦编译器知道该文件是项目的一部分(因为您放置了 mod语句的声明,所以知道代码在模块树中的哪个位置),项目中的其他文件应使用声明该文件的路径来引用加载文件的代码,换句话说,mod 不是你可能在其他编程语言中看到的 “include” 操作。

接下来,我们将把hosting模块提取到其自己的文件中。由于hostingfront_of_house的子模块,而不是根模块,因此我们将在新目录中为hosting创建一个文件,该目录将以模块树中的祖先命名,即src/front_of_house

要开始移动hosting,我们将更改src/front_of_house.rs,使其仅包含hosting模块的声明:

代码语言:rust
复制
pub mod hosting;

接下来,我们将创建一个 src/front_of_house 目录和一个 hosting.rs 文件来包含在 hosting 模块中定义的内容:

代码语言:rust
复制
pub fn add_to_waitlist() {}

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

现在我们就完成了这个优化,整体的目录结构如下所示:

代码语言:shell
复制
restaurant_pro
├── Cargo.lock
├── Cargo.toml
├── src
   ├── front_of_house
   │   └── hosting.rs
   ├── front_of_house.rs
   └── lib.rs

备用文件路径 到目前为止,我们已经介绍了Rust编译器使用的最具惯用性的文件路径,但Rust还支持一种较旧的文件路径风格。对于在crate根目录中声明的名为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 关键字将其公开。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 内容
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档