mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2026-08-19 12:43:28 +08:00
Updated src/packages_crates_and_modules/separating_modules.md'.
This commit is contained in:
2
projects/restaurant/src/front_of_house.rs
Normal file
2
projects/restaurant/src/front_of_house.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod hosting;
|
||||
|
||||
1
projects/restaurant/src/front_of_house/hosting.rs
Normal file
1
projects/restaurant/src/front_of_house/hosting.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub fn add_to_waitlist() {}
|
||||
@@ -1,13 +1,7 @@
|
||||
mod front_of_house {
|
||||
pub mod hosting {
|
||||
pub fn add_to_waitlist() {}
|
||||
}
|
||||
}
|
||||
|
||||
use crate::front_of_house::hosting;
|
||||
mod front_of_house;
|
||||
|
||||
pub mod customer {
|
||||
use super::hosting;
|
||||
use crate::front_of_house::hosting;
|
||||
|
||||
pub fn eat_at_restaurant() {
|
||||
hosting::add_to_waitlist();
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# 拆分模组为不同文件
|
||||
|
||||
到目前为止,本章的所有示例都把多个模组,定义在一个文件中。当模组变大时,咱们就会想要把他们的定义,移入到单独文件中,这样代码更容易浏览。
|
||||
到目前为止,这一章的所有示例都在一个文件中定义了多个模组。当模组变大时,咱们就可能希望迁移他们的定义到单独文件,使代码更易于导览。
|
||||
|
||||
例如,我们来从 [清单 7-17](./the_use_keyword.md#listing_7-17) 中,包含了多个餐厅模组的代码开始。我们将把这些模组提取到一些文件中,而不是把所有模组都定义在代码箱的根文件里。在本例中,代码箱的根文件为 `src/lib.rs`,但这一过程也适用于根文件为 `src/main.rs` 的二进制代码箱。
|
||||
例如,我们来从 [清单 7-17](./the_use_keyword.md#listing_7-17) 中有着多个餐厅模组的代码开始。我们将提取模组到文件中,而不是让全部模组都定义在代码箱的根文件中。在这一情形下,代码箱的根文件为 `src/lib.rs`,但这一过程也适用于根文件为 `src/main.rs` 的二进制代码箱。
|
||||
|
||||
首先,我们将把 `front_of_house` 这个模组提取到他自己的文件中。请移除 `front_of_house` 模组的花括号内的代码,只留下 `mod front_of_house;` 这个声明,这样 `src/lib.rs` 文件就包含着下面清单 7-21 所示的代码。请注意,在创建出清单 7-22 中的 `src/front_of_house.rs` 文件前,这段代码将不会编译。
|
||||
首先,我们将提取 `front_of_house` 模组到他自己的文件。请移除 `front_of_house` 模组花括号内的代码,只留下 `mod front_of_house;` 声明,以便 `src/lib.rs` 文件包含下面清单 7-21 中所示的代码。请注意,在我们创建清单 7-22 中的 `src/front_of_house.rs` 文件前,这段代码将不编译。
|
||||
|
||||
|
||||
<a name="listing_7-21"></a>
|
||||
文件名:`src/lib.rs`
|
||||
|
||||
```rust
|
||||
@@ -19,11 +20,12 @@ pub fn eat_at_restaurant() {
|
||||
}
|
||||
```
|
||||
|
||||
*清单 7-21:声明出其模组代码主体,将位于 `src/front_of_house.rs` 中的 `front_of_house` 模组*
|
||||
**清单 7-21**:声明`front_of_house` 模组,其主体将位于 `src/front_of_house.rs`
|
||||
|
||||
接下来,将原先花括符中的代码,放入一个名为 `src/front_of_house.rs` 的新文件中,如下清单 7-22 所示。编译器之所以知道要在这个文件中查找,是因为他在代码箱根中,看到了名为 `front_of_house` 的模组声明。
|
||||
接下来,将曾在那个花括符中的代码放入名为 `src/front_of_house.rs` 的新文件中,如下清单 7-22 中所示。编译器知道要在这个文件中查找,因为他在代码箱根中遇到了名为 `front_of_house` 的模组声明。
|
||||
|
||||
|
||||
<a name="listing_7-22"></a>
|
||||
文件名:`src/front_of_house.rs`
|
||||
|
||||
```rust
|
||||
@@ -32,13 +34,13 @@ pub mod hosting {
|
||||
}
|
||||
```
|
||||
|
||||
*清单 7-22:`src/front_of_house.rs` 中 `front_of_house` 模组内部的定义*
|
||||
**清单 7-22**:`src/front_of_house.rs` 中 `front_of_house` 模组内的定义
|
||||
|
||||
请注意,在咱们的模组树中,咱们只需使用 `mod` 声明加载某个文件 *一次*。一旦编译器知道了该文件是项目的一部分(且编译器会因咱们放置 `mod` 语句位置,而知道该代码位处模组树中何处),咱们项目中的其他文件,就应能使用 [“引用模组树中某个项目的路径”](./paths.md) 小节中介绍的到其声明处的路径,引用该加载文件的代码。换句话说,`mod` 并 *不是* 咱们在其他编程语言中,可能会看到的 “包含” 操作。
|
||||
请注意,咱们只需在模组树中使用 `mod` 声明加载文件 *一次*。一旦编译器知道了该文件属于项目的一部分(并由于咱们放置 `mod` 语句之处而知道代码在模组树中的何处),咱们项目中的其他文件,应使用其被声明处的路径来引用已加载文件的代码,如同 [“引用模组树中项目的路径”](./paths.md) 小节中所介绍的。换句话说,`mod` *不是* 咱们可能已在其他编程语言中看到的 “包含,include” 操作。
|
||||
|
||||
接下来,我们将把 `hosting` 模组提取到他自己的文件中。这个过程略有不同,因为 `hosting` 是 `front_of_house` 的一个子模组,而不是根模组。我们将把 `hosting` 的文件,放到一个模组树中的以其祖先命名的新目录中,在此情形下即为 `src/front_of_house`。
|
||||
接下来,我们将提取 `hosting` 模组到他自己的文件。这个过程略有不同,因为 `hosting` 是 `front_of_house`,而非根模组的子模组。我们将把 `hosting` 的文件放在一个新的目录中,该目录将以模组树中他的父辈命名,在此情形下即为 `src/front_of_house`。
|
||||
|
||||
要开始迁移 `hosting`,我们就要将 `src/front_of_house.rs`,修改为只包含 `hosting` 模组的声明:
|
||||
要开始迁移 `hosting`,我们修改 `src/front_of_house.rs` 为只包含 `hosting` 模组的声明:
|
||||
|
||||
文件名:`src/front_of_house.rs`
|
||||
|
||||
@@ -46,7 +48,8 @@ pub mod hosting {
|
||||
pub mod hosting;
|
||||
```
|
||||
|
||||
然后,我们创建一个 `src/front_of_house` 目录及一个存放 `hosting` 模组中所定义内容的 `hosting.rs` 文件:
|
||||
然后,我们创建一个 `src/front_of_house` 目录及一个 `hosting.rs` 文件,来包含构造于 `hosting` 模组中的定义:
|
||||
|
||||
|
||||
文件名:`src/front_of_house/hosting.rs`
|
||||
|
||||
@@ -54,34 +57,34 @@ pub mod hosting;
|
||||
pub fn add_to_waitlist() {}
|
||||
```
|
||||
|
||||
如果我们将 `hosting.rs` 文件放在 `src` 目录下,编译器就会期望 `hosting.rs` 的代码,属于在代码箱根中声明的 `hosting` 模组,而非作为 `front_of_house` 模组子模组声明的。确定哪些文件属于哪个模组代码的编译器规则,意味着目录和文件结构,会与模组树更加一致。
|
||||
相反若我们放置 `hosting.rs` 于 `src` 目录下,编译器就会期望 `hosting` 模组中的 `hosting.rs` 代码被声明于代码箱根中,而不是声明为 `front_of_house` 模组的子模组。编译器关于 “检查哪些文件以获取哪些模组的代码” 规则,意味着目录和文件会紧密地匹配模组树。
|
||||
|
||||
> **备用文件路径**
|
||||
>
|
||||
> 到目前为止,我们已经介绍了 Rust 编译器所使用的最常见文件路径,但 Rust 还支持一种较旧的文件路径风格。对于代码箱根中声明的一个名为 `front_of_house` 模组,编译器将在以下位置查找该模组的代码:
|
||||
|
||||
- `src/front_of_house.rs`(即这里讲到的);
|
||||
- `src/front_of_house/mod.rs`(较早样式,仍被支持的路径)。
|
||||
|
||||
> 对于 `front_of_house` 子模组的一个名为 `hosting` 的模组,编译器将在以下位置查找该模组的代码:
|
||||
|
||||
- `src/front_of_house/hosting.rs`(即这里讲到的);
|
||||
- `src/front_of_house/hosting/mod.rs`(较早样式,仍被支持的路径)。
|
||||
|
||||
> 若咱们对同一模组同时使用这两种样式,咱们将得到一个编译器报错。在同一个项目中对不同模组混合使用这两种样式是允许的,但这可能会让浏览咱们项目的人感到困惑。
|
||||
> 到目前为止,我们已介绍了 Rust 编译器用到的最惯用的文件路径,但 Rust 还支持一种较早的文件路径样式。对于声明于代码箱根中名为 `front_of_house` 的模组,编译器将在以下位置查找该模组的代码:
|
||||
>
|
||||
> 使用名为 `mod.rs` 文件样式的主要缺点,是咱们的项目可能会产生大量名为 `mod.rs` 的文件,当咱们在咱们的编辑器中同时打开这些文件时,这就可能造成混淆。
|
||||
> - `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` 中的函数调用,在无需任何修改下就将正常工作,尽管这些函数的定义现在位于别的文件中。随着模组规模扩大,这种技术允许咱们将其迁移至新文件。
|
||||
我们已经迁移各个模组的代码到单独文件,而模组树保持不变。`eat_at_restaurant` 中的函数调用在无需任何修改下仍将有效,即使定义位于不同文件。这一技巧允许咱们在模组大小增加时,迁移他们到新的文件。
|
||||
|
||||
请留意 `src/lib.rs` 中的 `pub use crate::front_of_house::hosting` 这个语句没有改变,且 `use` 语句对哪些文件被作为该代码箱的部分而被编译也没有任何影响。其中的 `mod` 关键字声明了这些模组,同时 Rust 会在与模组同名的文件中,查找要放入该模组的代码。
|
||||
请注意,`src/lib.rs` 中的 `pub use crate::front_of_house::hosting` 同样未曾改变,`use` 语句既对作为代码箱一部分编译的文件也无任何影响。`mod` 关键字声明模组,而 Rust 会在与模组同名的文件中查找进入该模组的代码。
|
||||
|
||||
|
||||
# 本章小节
|
||||
|
||||
Rust 允许咱们将包拆分为多个代码箱,并将代码箱拆分为模组,这样咱们就可以从一个模组,引用另一模组中所定义的那些项目。通过指定绝对路径或相对路径,咱们就可以做到这点。使用 `use` 语句,这些路径就被带入作用域,这样咱们就可以在该作用域中,对项目的多次引用使用一个更短的路径。模组代码默认是私有的,但咱们可通过添加 `pub` 关键字,将他们的定义构造为公开。
|
||||
Rust 允许咱们将包拆分为多个代码箱,并拆分代码箱为模组,以便咱们可以在一个模组中引用定义在另一模组中的项目。咱们可通过指定绝对路径或相对路径做到这点。这些路径可在 `use` 语句下带入作用域,以便咱们可以针对项目在该作用域中的多次引用,而使用较短的路径。默认情况下模组代码是私有的,但咱们可通过添加 `pub` 关键字,构造定义为公开。
|
||||
|
||||
在下一章中,我们将探讨标准库中的一些集合数据结构,在咱们良好组织的代码中,咱们就可以使用这些集合数据结构。
|
||||
在下一章中,我们将探讨标准库中的一些集合数据结构,咱们可在咱们良好组织的代码中使用他们。
|
||||
|
||||
|
||||
(End)
|
||||
|
||||
Reference in New Issue
Block a user