mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2024-12-26 12:50:42 +08:00
Refining Ch07.
This commit is contained in:
parent
e9c6e88ab8
commit
1ae19e883e
8
projects/backyard/Cargo.toml
Normal file
8
projects/backyard/Cargo.toml
Normal 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]
|
3
projects/backyard/src/main.rs
Normal file
3
projects/backyard/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
@ -3,38 +3,38 @@
|
|||||||
**Defining Modules to Control Scope and Privacy**
|
**Defining Modules to Control Scope and Privacy**
|
||||||
|
|
||||||
|
|
||||||
在本小节中,这里会讲到模组与模组系统的其他部分,分别是实现对各种项目(items, 变量、函数、结构体、枚举、模组、常量或别的项目)命名的 *路径(paths)*;将某个路径引入到作用域的 `use` 关键字;以及将那些项目构造为公共项目的 `pub` 关键字。这里还会讨论到 `as` 关键字、外部代码包,以及全局操作符(the glob operator)等等。
|
在本节中,我们将讨论模组和模组系统的其他部分,即允许咱们给项目取名的 *路径,paths*、将路径引入作用域的 `use` 关键字,以及将项目构造为公开的 `pub` 关键字等。我们还将讨论 `as` 关键字、外部包和 `glob` 操作符。
|
||||||
|
|
||||||
首先,这里将以今后在对代码进行组织时,易于参考的一个规则列表开始。随后就会对这些规则详细解释。
|
首先,我们将以一份方便咱们今后组织咱们代码的规则清单开始。然后,我们将详细解释每一条规则。
|
||||||
|
|
||||||
|
|
||||||
## 模组备忘单
|
## 模组速查表
|
||||||
|
|
||||||
**Modules Cheat Sheet**
|
**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` 模组。编译器将在以下位置,查找该模组的代码:
|
+ **声明模组**:在代码箱根文件中,咱们可以声明出新的模组;比如,咱们以 `mod garden;`,声明一个 ”花园“ 模组。编译器将在下面这些地方,查找该模组的代码:
|
||||||
- 内联代码(inline),位于紧随 `mod garden` 之后,取代分号的花括号里;
|
- 内联式,在替换 `mod garden` 后分号的花括号内;
|
||||||
- 文件 `src/garden.rs` 中;
|
- 文件 `src/garden.rs` 中;
|
||||||
- 文件 `src/garden/mod.rs` 中;
|
- 文件 `src/garden/mod.rs` 中。
|
||||||
|
|
||||||
+ **子模组的声明(declaring submodules)**:在任何非代码箱根文件中,都可声明出一些子模组来。比如,或许就要在 `src/garden.rs` 中,声明出 `mod vegetables;`;编译器将在那个以父模组命名的目录里的以下地方,查找那些子模组的代码:
|
+ **声明子模组**:在除代码箱根外的任何文件中,都可以声明子模组。例如,咱们可能会在 `src/garden.rs` 中,声明 `mod vegetables;`。编译器将在下面这些地方的父模组目录中,查找该子模组的代码:
|
||||||
- 内联代码,直接跟在 `mod vegetables` 之后,位处取代分号的花括号中;
|
- 内联式,直接跟在 `mod vegetables` 之后,代替分号的花括号内;
|
||||||
- 文件 `src/garden/vegetables.rs` 中;
|
- 文件 `src/garden/vegetables.rs` 中;
|
||||||
- 文件 `src/garden/vegetables/mod.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
|
```console
|
||||||
backyard
|
backyard
|
||||||
@ -47,7 +47,9 @@ backyard
|
|||||||
└── main.rs
|
└── main.rs
|
||||||
```
|
```
|
||||||
|
|
||||||
该代码箱的根文件,在此实例中即为 `src/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`
|
文件名:`src/garden.rs`
|
||||||
|
|
||||||
@ -70,6 +74,7 @@ fn main() {
|
|||||||
pub mod vegetables;
|
pub mod vegetables;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
而语句 `pub mod vegetables;` 表示在 `src/garden/vetables.rs` 中的代码也会被编译器包含:
|
而语句 `pub mod vegetables;` 表示在 `src/garden/vetables.rs` 中的代码也会被编译器包含:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@ -13,15 +13,14 @@
|
|||||||
|
|
||||||
而 *代码箱根,crate root*,则是个 Rust 编译器开始之处的源代码文件,并构成了咱们代码箱的 *根模组,root module*(我们将在 [定义控制作用域和隐私的模组](/packages_crates_and_modules/defining_modules.md) 小节,深入探讨模组)。
|
而 *代码箱根,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
|
```console
|
||||||
|
|
||||||
$ cargo new my-project --vcs=none
|
$ cargo new my-project --vcs=none
|
||||||
Created binary (application) `my-project` package
|
Created binary (application) `my-project` package
|
||||||
$ ls my-project
|
$ ls my-project
|
||||||
@ -30,9 +29,7 @@ $ ls my-project/src
|
|||||||
main.rs
|
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` 目录中放置一些文件,包可以有多个二进制代码箱:每个文件都将是个单独的二进制代码箱。
|
||||||
|
Loading…
Reference in New Issue
Block a user