Refining Ch07.

This commit is contained in:
Peng Hailin, 2023-12-19 21:52:54 +08:00
parent e9c6e88ab8
commit 1ae19e883e
4 changed files with 37 additions and 24 deletions

View File

@ -0,0 +1,8 @@
[package]
name = "backyard"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View File

@ -3,38 +3,38 @@
**Defining Modules to Control Scope and Privacy**
在本小节中这里会讲到模组与模组系统的其他部分分别是实现对各种项目items, 变量、函数、结构体、枚举、模组、常量或别的项目)命名的 *路径paths*;将某个路径引入到作用域的 `use` 关键字;以及将那些项目构造为公共项目的 `pub` 关键字。这里还会讨论到 `as` 关键字、外部代码包以及全局操作符the glob operator等等
在本节中,我们将讨论模组和模组系统的其他部分,即允许咱们给项目取名的 *路径paths*、将路径引入作用域的 `use` 关键字,以及将项目构造为公开的 `pub` 关键字等。我们还将讨论 `as` 关键字、外部包和 `glob` 操作符
首先,这里将以今后在对代码进行组织时,易于参考的一个规则列表开始。随后就会对这些规则详细解释
首先,我们将以一份方便咱们今后组织咱们代码的规则清单开始。然后,我们将详细解释每一条规则
## 模组备忘单
## 模组速查表
**Modules Cheat Sheet**
下面就是模组、路径、`use` 关键字与 `pub` 关键字在编译器中工作原理的快速参考,以及多数开发者组织他们代码的方式。贯穿这一整章,都将逐一介绍这些规则,而这也是作为理解 Rust 模组工作原理的极佳之处
这里我们提供了有关模组、路径、`use` 关键字和 `pub` 关键字,在编译器中如何运作,以及大多数开发人员如何组织代码的快速参考。我们将在本章节中,逐个讨论这些规则的示例,但这是个很到的,作为模组工作原理的提醒的地方
- **自代码箱根开始start from the crate root**:在编译代码箱时,编译器首先看的是代码箱根文件(对于库代码箱,通常为 `src/lib.rs`,或者二进制代码箱的 `src/main.rs`)中,要编译的代码;
- **从代码箱根开始**:编译代码箱时,编译器首先会在代码箱根文件(通常是库代码箱的 `src/lib.rs`,或二进制代码箱的 `src/main.rs`)中,查找要编译的代码;
+ **模组的声明declaring modules**:在代码箱根文件中,就可声明一些新的模组;比方说,使用 `mod gargen;`,而声明出一个 `garden` 模组。编译器将在以下位置,查找该模组的代码:
- 内联代码inline位于紧随 `mod garden` 之后,取代分号的花括号里
+ **声明模组**:在代码箱根文件中,咱们可以声明出新的模组;比如,咱们以 `mod garden;`,声明一个 ”花园“ 模组。编译器将在下面这些地方,查找该模组的代码:
- 内联式,在替换 `mod garden` 后分号的花括号内
- 文件 `src/garden.rs` 中;
- 文件 `src/garden/mod.rs`
- 文件 `src/garden/mod.rs`
+ **子模组的声明declaring submodules**:在任何非代码箱根文件中,都可声明出一些子模组来。比如,或许就要在 `src/garden.rs` 中,声明出 `mod vegetables`;编译器将在那个以父模组命名的目录里的以下地方,查找那些子模组的代码:
- 内联代码,直接跟在 `mod vegetables` 之后,位处取代分号的花括号中
+ **声明子模组**:在除代码箱根外的任何文件中,都可以声明子模组。例如,咱们可能会在 `src/garden.rs` 中,声明 `mod vegetables;`。编译器将在下面这些地方的父模组目录中,查找该子模组的代码:
- 内联式,直接跟在 `mod vegetables` 之后,代替分号的花括号内
- 文件 `src/garden/vegetables.rs` 中;
- 文件 `src/garden/vegetables/mod.rs` 中。
- **模组中代码的路径paths to code in modules**:一旦模组成为代码箱的一部分,就可以在这同一个代码箱中的任何地方,在隐私规则允许的情况下,运用代码路径,对那个模组中的代码加以引用。比如,那个 “garden” “vegetables” 模组中的 `Asparagus` 类型,就可`crate::garden::vegetables::Asparagus` 处找到。
- **模组中代码的路径**:一旦某个模组成为咱们代码箱的一部分,只要隐私规则允许,咱们就可以在同一代码箱的任何其他地方,使用代码的路径来引用该模组中的代码。例如,花园蔬菜模组中的 `Asparagus` (芦笋)类型,就可以`crate::garden::vegetables::Asparagus` 处找到。
- **私有与公private vs public**:模组里的代码,默认对该模组的父模组是私有的。要令到模组成为公共的,就要使用 `pub mod` 而非 `mod` 来声明该模组。而要令到公共模组里的各个项目也成为公共的,就要在这些项目的声明之前,使用 `pub` 关键字
- **私有与公开**:模组内的代码默认对其父模组是私有的。要将某个模组构造为公开,可使用 `pub mod` 代替 `mod` 声明该模组。要将某个公开模组中的项目,也构造为公开,请在其声明前使用 `pub`
- **`use` 关键字**:在某个作用域里,`use` 关键字创建出到项目的快捷方式,以减少长路径的重复。在任何能够引用到 `crate::garden::vegetables::Asparagus` 的作用域中,都可以使用 `use crate::garden::vegetables::AspAragus;` 语句,创建出一个快捷方式,并于随后只需写出 `Asparagus`,就可在该作用域中,使用那个类型。
- **`use` 关键字**:在作用域中,`use` 关键字会创建出到项目的快捷方式,以减少长路径的重复。在任何可以引用 `crate::garden::vegetables::Asparagus` 的作用域中,咱们都可以使用 `use crate::garden::vegetables::Asparagus;` 创建出一个快捷方式,并在那以后,咱们就只需写下 `Asparagus`,就可以在该作用域中使用这个类型。
在此,我们创建了一个说明这些规则的名为 `backyard` 的二进制代码箱。这个代码箱的目录也称为 `backyard`,其中包含下面这些文件和目录:
下面是个名为 `backyard`、对这些规则加以演示的二进制代码箱。该代码箱的目录,也叫做 `backyard`,包含了下面这些文件与目录:
```console
backyard
@ -47,7 +47,9 @@ backyard
└── main.rs
```
该代码箱的根文件,在此实例中即为 `src/main.rs`,包含下面的代码:
本例中的代码箱根文件是 `src/main.rs`,他包含:
文件名:`src/main.rs`
@ -62,7 +64,9 @@ fn main() {
}
```
语句 `pub mod garden;`,表示编译器会包含他在 `src/garden.rs` 中找到的代码,也就是:
`pub mod garden;` 这行告诉编译器,要包含其在 `src/garden.rs` 中找到的代码,即:
文件名:`src/garden.rs`
@ -70,6 +74,7 @@ fn main() {
pub mod vegetables;
```
而语句 `pub mod vegetables;` 表示在 `src/garden/vetables.rs` 中的代码也会被编译器包含:
```rust

View File

@ -13,15 +13,14 @@
*代码箱根crate root*,则是个 Rust 编译器开始之处的源代码文件,并构成了咱们代码箱的 *根模组root module*(我们将在 [定义控制作用域和隐私的模组](/packages_crates_and_modules/defining_modules.md) 小节,深入探讨模组)。
*包package* 是提供了一组功能的一或多个代码箱的捆绑。包会包含一个描述如何构建这些代码箱的 `Cargo.toml` 文件。Cargo 实际上就是个包含了咱们用来构建代码的命令行工具的包。Cargo 包还包含该二进制代码箱所依赖的库代码箱。其他项目可以依赖于 Cargo 的库代码箱,使用与 Cargo 这个命令行工具所使用的同样逻辑。
*包package* 是提供了一组功能的一或多个代码箱的捆绑。包会包含一个描述如何构建这些代码箱的 `Cargo.toml` 文件。Cargo 实际上就是个包含了咱们用来构建代码的命令行工具的包。Cargo 包还包含该二进制代码箱所依赖的库代码箱。其他项目可以依赖于 Cargo 的库代码箱,使用与 Cargo 这个命令行工具所使用的同样逻辑。
某个包可以包含任意数量的二进制代码箱,但最多只能包含一个库代码箱。某个包必须至少包含一个代码箱,无论是库代码箱,还是二进制代码箱。
一个包可以包含任意数量的二进制代码箱,但最多只能包含一个库代码箱。一个包必须至少包含一个代码箱,无论是库代码箱,还是二进制代码箱。
我们来看看当我们创建出某个软件包时,会发生什么。首先,我们输入命令 `cargo new`
我们来看看,在我们创建某个软件包时,会发生什么。首先,我们输入命令 `cargo new`
```console
$ cargo new my-project --vcs=none
Created binary (application) `my-project` package
$ ls my-project
@ -30,9 +29,7 @@ $ ls my-project/src
main.rs
```
在运行了 `cargo new` 之后,这里便使用 `ls` 来查看 Cargo 创建了些什么。在该项目目录下,有着一个 `Cargo.toml` 文件,这就给到咱们一个代码包。其中还有一个包含了 `main.rs``src` 目录。在文本编辑器中打开 `Cargo.toml` 文件,就会注意到其中并未提及 `src/main.rs`。Cargo 遵循了 `src/main.rs` 即为与该代码包同名二进制代码箱箱根这样一条约定。与此类似Cargo 还知道,在代码包目录包含了 `src/lib.rs` 时,那么这个代码包就包含了与该包同名的一个库代码箱,而那个 `src/lib.rs` 就是该库代码箱的箱根。Cargo 会将代码箱根文件,传递给 `rustc`,来构建出相应的库或二进制程序。
这里有一个只包含了 `src/main.rs` 的代码包,意味着他只包含了名为 `my-project` 的一个二进制代码箱。而在代码包同时包含了 `src/main.rs``src/lib.rs` 时,他就会有两个代码箱:一个二进制和一个库代码箱,二者都有着与该代码包同样的名字。通过将一些文件放入到 `src/bin` 目录Rust 包就可以有多个二进制代码箱:其中的每个文件,都将是单独的二进制代码箱。
运行 `cargo new` 后,我们使用 `ls` 查看 Cargo 创建了什么。在该项目目录中,有个 `Cargo.toml` 文件,给到我们一个包。还有个包含了 `main.rs``src` 目录。请用咱们的文本编辑器,打开 `Cargo.toml`,注意其中没有提到 `src/main.rs`。Cargo 遵循,`src/main.rs` 是与该软件包同名的二进制代码箱的代码箱根这一惯例。同样Cargo 知道,如果包目录中包含 `src/lib.rs`,那么该包中就包含一个,与该包同名的库代码箱,而 `src/lib.rs` 就是其代码箱根。Cargo 会将代码箱根文件,传递给 `rustc` 以构建出该库或二进制程序。
这里,我们有着一个只包含 `src/main.rs` 的包,意味着他只包含一个名为 `my-project` 的二进制代码箱。如果某个包包含 `src/main.rs``src/lib.rs`,那么他就有两个代码箱:一个二进制代码箱和一个库代码箱,且两个代码箱都有着与该包同样的名字。通过在 `src/bin` 目录中放置一些文件,包可以有多个二进制代码箱:每个文件都将是个单独的二进制代码箱。