From 1ae19e883e58342be6ecd9d662f8e68e3c078488 Mon Sep 17 00:00:00 2001 From: "Peng Hailin," Date: Tue, 19 Dec 2023 21:52:54 +0800 Subject: [PATCH] Refining Ch07. --- projects/backyard/Cargo.toml | 8 ++++ projects/backyard/src/main.rs | 3 ++ .../defining_modules.md | 37 +++++++++++-------- .../packages_and_crates.md | 13 +++---- 4 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 projects/backyard/Cargo.toml create mode 100644 projects/backyard/src/main.rs diff --git a/projects/backyard/Cargo.toml b/projects/backyard/Cargo.toml new file mode 100644 index 0000000..8c822ec --- /dev/null +++ b/projects/backyard/Cargo.toml @@ -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] diff --git a/projects/backyard/src/main.rs b/projects/backyard/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/projects/backyard/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/src/packages_crates_and_modules/defining_modules.md b/src/packages_crates_and_modules/defining_modules.md index 89729e8..60436d8 100644 --- a/src/packages_crates_and_modules/defining_modules.md +++ b/src/packages_crates_and_modules/defining_modules.md @@ -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 diff --git a/src/packages_crates_and_modules/packages_and_crates.md b/src/packages_crates_and_modules/packages_and_crates.md index 832aea2..f54c728 100644 --- a/src/packages_crates_and_modules/packages_and_crates.md +++ b/src/packages_crates_and_modules/packages_and_crates.md @@ -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` 目录中放置一些文件,包可以有多个二进制代码箱:每个文件都将是个单独的二进制代码箱。