mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2026-08-22 14:13:28 +08:00
Updated 'src/packages_crates_and_modules/separating_modules.md'.
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
- [使用包、代码箱与模组对日趋增长的项目进行管理](Ch07_Managing_Growing_Projects_with_Packages_Crates_and_Modules.md)
|
||||
- [代码包与代码箱](packages_crates_and_modules/packages_and_crates.md)
|
||||
- [定义用于控制作用域及隐私性的模组](packages_crates_and_modules/defining_modules.md)
|
||||
- [用于引用模组树中某个项目的路径](packages_crates_and_modules/paths.md)
|
||||
- [引用模组树中某个项目的路径](packages_crates_and_modules/paths.md)
|
||||
- [使用 `use` 关键字将路径带入作用域](packages_crates_and_modules/the_use_keyword.md)
|
||||
- [将模组分成不同文件](packages_crates_and_modules/separating_modules.md)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# 用于引用模组树中项目的路径
|
||||
# 引用模组树中项目的路径
|
||||
|
||||
**Paths for Referring to an Item in the Module Tree**
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
**Separating Modules into Different Files**
|
||||
|
||||
到目前为止,本章的全部示例,都是将多个模组定义在一个文件中的。在模组变得大起来时,就会打算将他们的定义,迁移到单独文件,从而令到代码易于导览。
|
||||
|
||||
比如,这里就从清单 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` 文件之前,这是不会编译的。
|
||||
|
||||
文件名:`src/lib.rs`
|
||||
|
||||
@@ -20,9 +22,10 @@ pub fn eat_at_restaurant() {
|
||||
}
|
||||
```
|
||||
|
||||
*清单 7-21:声明出其模组代码体将在 `src/front_of_house.rs` 中的 `front_of_house` 模组*
|
||||
*清单 7-21:声明出其模组代码主体,将位于 `src/front_of_house.rs` 中的 `front_of_house` 模组*
|
||||
|
||||
接下来,将原先花括符中的代码,放入一个名为 `src/front_of_house.rs` 的新文件中,如下清单 7-22 所示。编译器之所以知道要在这个文件中查找,是因为他在代码箱根中,看到了名为 `front_of_house` 的模组声明。
|
||||
|
||||
接下来,就要把原先在花括号中的代码,放入到一个新的名为 `src/front_of_house.rs` 文件中,如下清单 7-22 中所示。由于编译器在该代码箱根中,找到了名字 `front_of_house`,因此他就明白要在这个文件中看看。
|
||||
|
||||
文件名:`src/front_of_house.rs`
|
||||
|
||||
@@ -32,13 +35,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` 语句放置于于何处,而掌握了该代码在模组树中所处的位置),项目中的其他文件,则应如同之前 [用于引用模组树中项目的路径](#用于引用目录树中项目的路径) 小节中,曾讲到的到模组声明处的路径,来引用那个文件中的代码。也就是说,这里的 `mod` *并非* 其他编程语言有的那种 “include” 操作。
|
||||
请注意,在咱们的模组树中,咱们只需使用 `mod` 声明加载某个文件 *一次*。一旦编译器知道了该文件是项目的一部分(且编译器会因咱们放置 `mod` 语句位置,而知道该代码位处模组树中何处),咱们项目中的其他文件,就应能使用 [“引用模组树中某个项目的路径”](./paths.md) 小节中介绍的到其声明处的路径,引用该加载文件的代码。换句话说,`mod` 并 *不是* 咱们在其他编程语言中,可能会看到的 “包含” 操作。
|
||||
|
||||
接下来,就要将那个 `hosting` 模组,提取到他自己的文件了。而由于 `hosting` 是 `front_of_house` ,而非根模组,的子模组,因此过程略有不同。这里将把 `hosting` 模组的文件,放在模组树中以其父辈命名的一个新目录中,此示例中即为 `src/front_of_house`。
|
||||
接下来,我们将把 `hosting` 模组提取到他自己的文件中。这个过程略有不同,因为 `hosting` 是 `front_of_house` 的一个子模组,而不是根模组。我们将把 `hosting` 的文件,放到一个模组树中的以其祖先命名的新目录中,在此情形下即为 `src/front_of_house`。
|
||||
|
||||
这里要将 `src/front_of_house.rs` 文件,修改为只包含 `hosting` 模组声明,以开始对 `hosting` 的迁移:
|
||||
要开始迁移 `hosting`,我们就要将 `src/front_of_house.rs`,修改为只包含 `hosting` 模组的声明:
|
||||
|
||||
文件名:`src/front_of_house.rs`
|
||||
|
||||
@@ -46,7 +49,7 @@ pub mod hosting {
|
||||
pub mod hosting;
|
||||
```
|
||||
|
||||
随后就要创建一个 `src/front_of_house` 的目录,和一个文件 `src/front_of_house/hosting.rs`,来包含在 `hosting` 模组中构造的那些定义:
|
||||
然后,我们创建一个 `src/front_of_house` 目录及一个存放 `hosting` 模组中所定义内容的 `hosting.rs` 文件:
|
||||
|
||||
文件名:`src/front_of_house/hosting.rs`
|
||||
|
||||
@@ -54,36 +57,34 @@ pub mod hosting;
|
||||
pub fn add_to_waitlist() {}
|
||||
```
|
||||
|
||||
相反如果将 `hosting.rs` 放在 `src` 目录,那么编译器就会以为 `hosting.rs` 的代码,是在声明于代码箱根部的 `hosting` 模组中的,而不是那个 `front_of_house` 模组的子模组中的。为了获取模组代码,而要查看那些文件方面的编译器规则,就表明这些目录与文件,甚为紧密地于模组树结构相匹配。
|
||||
如果我们将 `hosting.rs` 文件放在 `src` 目录下,编译器就会期望 `hosting.rs` 的代码,属于在代码箱根中声明的 `hosting` 模组,而非作为 `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 编译器所用到的最惯用的文件路径;但较早的文件路径仍被支持。
|
||||
>
|
||||
> 对于定义在代码箱根部的名为 `front_of_house` 模组,编译器会在下面这些地方查找该模组的代码:
|
||||
> 使用名为 `mod.rs` 文件样式的主要缺点,是咱们的项目可能会产生大量名为 `mod.rs` 的文件,当咱们在咱们的编辑器中同时打开这些文件时,这就可能造成混淆。
|
||||
|
||||
- `src/front_of_house.rs` (即这里讲到的);
|
||||
- `src/front_of_house/mod.rs` (较早的,仍被支持的路径)。
|
||||
我们已将各个模组的代码移至独立文件中,同时模组树保持不变。`eat_at_restaurant` 中的函数调用,在无需任何修改下就将正常工作,尽管这些函数的定义现在位于别的文件中。随着模组规模扩大,这种技术允许咱们将其迁移至新文件。
|
||||
|
||||
> 而对于作为 `front_of_house` 的子模组的名为 `hosting` 的模组,编译器会在以下地方查找该模组的代码:
|
||||
请留意 `src/lib.rs` 中的 `pub use crate::front_of_house::hosting` 这个语句没有改变,且 `use` 语句对哪些文件被作为该代码箱的部分而被编译也没有任何影响。其中的 `mod` 关键字声明了这些模组,同时 Rust 会在与模组同名的文件中,查找要放入该模组的代码。
|
||||
|
||||
- `src/front_of_house/hosting.rs` (即这里讲到的);
|
||||
- `src/front_of_house/hosting/mod.rs` (较早的,仍被支持的路径)。
|
||||
|
||||
> 对于同一模组,若同时使用这两种文件路径,那么就会得到一个编译器错误。而对同一项目中的不同模组,采用不同方式的文件路径是被允许的,只是会对那些导览项目的人造成困扰。
|
||||
>
|
||||
> 使用名为 `mod.rs` 文件方式的主要缺点,即那样的话,项目最终会以许多名为 `mod.rs` 文件而终结,在代码编辑器中,同时打开这些 `mod.rs` 文件,那么就会感到混乱。
|
||||
|
||||
将各个模组的代码,移入到单独文件现在就完成了,而模组树还是保持原来那样。尽管模组定义存在于不同文件中,但是无需任何修改,那个在 `eat_at_restaurant` 中的函数调用仍会工作。这种技巧,就实现了在模组大小增长时,将其迁移到新的文件中。
|
||||
|
||||
请注意 `src/lib.rs` 中的那个 `pub use crate::front_of_house::hosting;` 语句,同样不曾改变,而那个 `use` 也不会对哪些文件作为代码箱的部分,而被编译有任何的影响。`mod` 关键字定义了模组,而 Rust 则会在与该模组有着同样名字的文件中,查找要进到那个模组中的代码。
|
||||
|
||||
# 本章小节
|
||||
|
||||
Rust 实现了包拆分为多个代码箱,进而将代码箱拆分为多个模组,这样就可以从一个模组,对定义在另一模组中的程序项目加以引用。通过指明绝对或相对路径,就可以做到这点。使用 `use` 语句,就可以将这些程序项目的路径,带入到作用域,如此就可以在那个作用域中,多次用到所带入的程序项目时,使用较简短的路径。默认下模组代码是私有的,但可通过添加 `pub` 关键字,而将一些定义构造为公开的。
|
||||
Rust 允许咱们将包拆分为多个代码箱,并将代码箱拆分为模组,这样咱们就可以从一个模组,引用另一模组中所定义的那些项目。通过指定绝对路径或相对路径,咱们就可以做到这点。使用 `use` 语句,这些路径就被带入作用域,这样咱们就可以在该作用域中,对项目的多次引用使用一个更短的路径。模组代码默认是私有的,但咱们可通过添加 `pub` 关键字,将他们的定义构造为公开。
|
||||
|
||||
下一章中,就会看看,可在本地组织良好代码中,使用到的标准库中的一些集合数据结构(collection data structures)。
|
||||
在下一章中,我们将探讨标准库中的一些集合数据结构,在咱们良好组织的代码中,咱们就可以使用这些集合数据结构。
|
||||
|
||||
|
||||
(End)
|
||||
|
||||
@@ -192,7 +192,7 @@ pub fn eat_at_restaurant() {
|
||||
}
|
||||
```
|
||||
|
||||
*清单 7-17:使用 `pub use` 让任何代码都可以从新作用域中使用某个名字*
|
||||
<a name="listing-7-17"></a> *清单 7-17:使用 `pub use` 让任何代码都可以从新作用域中使用某个名字*
|
||||
|
||||
在这一修改之前,外部代码必须使用 `restaurant::front_of_house::hosting::add_too_waitlist()` 路径,来调用 `add_to_waitlist` 函数,这还需要 `front_of_house` 模组被标记为 `pub`。现在,这个 `pub use` 已经从该根模组中,重新导出了 `hosting` 模组,外部代码就可以使用 `restaurant::hosting::add_to_waitlist()` 路径了。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user