From 73c7f702c80e33c9006e10f35f2a5e70bc0a863b Mon Sep 17 00:00:00 2001 From: "rust-lang.xfoss.com" Date: Fri, 1 Dec 2023 17:48:14 +0800 Subject: [PATCH] Refining Ch01. --- src/getting_started/hello_cargo.md | 38 ++++++++++++--------- src/getting_started/hello_world.md | 53 ++++++++++++++++-------------- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/getting_started/hello_cargo.md b/src/getting_started/hello_cargo.md index 95a4703..f13baed 100644 --- a/src/getting_started/hello_cargo.md +++ b/src/getting_started/hello_cargo.md @@ -1,34 +1,39 @@ # 你好,Cargo! -Cargo 是 Rust 的构建系统和包管理器。由于 Cargo 处理了很多任务,诸如构建代码、下载代码所依赖的库,以及这些库的构建等等,因此绝大多数 Rust 公民都使用这个工具,来管理他们的 Rust 项目。(我们把这些库叫做代码需要依赖(we call the libraries that your code needs *dependencies*)。) +Cargo 是 Rust 的构建系统,与软件包管理器。大多数 Rustaceans,都会使用这个工具,来管理他们的 Rust 项目,因为 Cargo 会为咱们处理很多任务,例如构建咱们的代码、下载咱们代码所依赖的库,并构建这些库。(我们把咱们代码所需的库,称为 *依赖项, dependencies*)。 -对于最简单的那些 Rust 程序,比如才写的那个,是没有任何依赖的。因此若使用 Cargo 来构建这个 `Hello, World!` 项目,那么就只会用到 Cargo 处理代码构建的部分。而随着更为复杂 Rust 程序的编写,就会添加依赖,而在开始一个用到 Cargo 的项目时,完成依赖添加就会容易得多。 +对于那些最简单的 Rust 程序,就像我们目前为止编写的那个程序一样,并无任何依赖项。如果咱们使用 Cargo 构建那个 "Hello, world!" 项目,他就只会使用 Cargo 中,负责构建代码的部分。而当咱们编写更复杂的 Rust 程序时,咱们将添加一些依赖项,这时咱们如果使用 Cargo 启动某个项目,那么添加依赖项,就会容易得多。 -由于广大 Rust 项目都用到了 Cargo,本书其余部分就假定了也使用 Cargo。若使用了在 [安装](#安装) 小节中提到的官方安装器进行的 Rust 安装,那么Cargo就已与 Rust 一起安装好了。而若是以其他方式安装的 Rust,那么就要通过在终端中敲入下面的命令,来检查 Cargo 是否已安装妥当: +由于绝大多数 Rust 项目都使用 Cargo,因此本书的其余部分,假定咱们也在使用 Cargo。如果咱们使用 [“安装”](installation.md) 小节中讨论的官方安装程序,那么 Cargo 会与 Rust 一起安装。如果咱们通过其他方式安装的 Rust,那么请在咱们的终端中,输入以下命令检查 Cargo 是否已安装: ```console $ cargo --version ``` -若能看到版本号,那么就有了这个工具!而若看到错误,诸如 `command not found`,就请查看你的安装方式的文档,找到怎样单独安装 Cargo 的方法。 +如果咱们看到某个版本号,说明已经安装!如果看到 `command not found` 等错误,则请查看咱们安装方式的文档,确定出如何单独安装 Cargo。 -## 使用 Cargo 创建项目 +## 用 Cargo 创建一个项目 + + +咱们来使用 Cargo 创建一个新项目,并看看他与最初的 "Hello, world!" 项目有何不同。请回到咱们的 `projects` 目录(或咱们决定存储代码的任何地方)。然后,在任何操作系统上,运行以下程序: -下面来使用 Cargo 创建一个新项目,并看看与原先的 “Hello, World!” 项目有何不同。现在导航至 `projects` 目录(或确定下来的保存代码的其他地方)。然后不论在那个操作系统之上,运行下面的命令: ```console $ cargo new hello_cargo $ cd hello_cargo ``` -这第一个命令创建出了一个新的名为 `hello_cargo` 目录。这里就已将项目命名为了 `hello_cargo`,然后 Cargo 将其文件创建在了同名的目录里面。 +第一条命令,会创建出一个名为 `hello_cargo` 的新目录及项目。我们将项目命名为 `hello_cargo`,而 Cargo 就会在同名目录下,创建他的一些文件。 -进入到 `hello_cargo` 目录并列出那些文件。就会看到 Cargo 已经为我们生成了两个文件和一个目录:一个 `Cargo.toml`文件与一个里头有着 `main.rs` 文件的 `src` 目录。 +进入 `hello_cargo` 目录并列出其中的文件。咱们将看到,Cargo 为我们生成了两个文件和一个目录:一个 `Cargo.toml` 文件和一个包含 `main.rs` 文件的 `src` 目录。 -`cargo new` 还初始化了一个新的、带有 `.gitignore` 文件的 Git 代码仓库。若是在一个既有的 Git 代码仓库运行的 `cargo new`,那么就不会生成那些 Git 文件;通过运用 `cargo new --vcs=git` 可重写此行为。 -> 注意:Git 是种常用的版本控制系统。可通过上面的 `--vcs` 命令行参数,让 `cargo new` 使用其他版本控制系统或不使用版本控制系统。请运行 `cargo new --help`命令来查看所有可用选项。 +他还初始化了一个新的 Git 仓库和一个 `.gitignore` 文件。如果咱们在现有的 Git 仓库中运行 `cargo new`,就不会生成这些 Git 文件;咱们可以使用 `cargo new --vcs=git`,来覆盖这一行为。 + +> **注意**:Git 是种常见的版本控制系统。通过使用 `--vcs` 命令行开关,咱们可以将 `cargo new`,改为使用其他版本控制系统,或不使用版本控制系统。请运行 `cargo new --help`,查看可用选项。 + +在咱们所选的文本编辑器中,打开 `Cargo.toml`。他应该类似于清单 1-2 中的代码。 文件名:`Cargo.toml` @@ -42,17 +47,18 @@ edition = '2021' [dependencies] ``` -*清单 1-2:由 `cargo new` 所生成的 `Cargo.toml` 的内容* +*清单 1-2:由 `cargo new` 生成的 `Cargo.toml` 内容* -该文件是 [TOML](https://toml.io/) ( *Tom's Obvious, Minimal Language* ) 格式的,这是 Cargo 的配置格式。 -该文件的第一行, `[package]`,是个小节标题,表示接下来的语句是在对一个包进行配置。随着往这个文件添加越来越多的信息,就会添加其他小节。 +该文件属于 [TOML](https://toml.io/)( *Tom's Obvious, Minimal Language* )格式,是 Cargo 的配置格式。 -接下来的三行,对 Cargo 用于编译程序所需的信息进行了配置:项目名称、版本号及要使用的 Rust 版本。在 [附录 E](Appendix_E.md) 中会讲到这个 `edition` 关键字。 +其中第一行,`[package]` 是个表示以下语句,正在配置某个软件包的小节标题。随着咱们向该文件添加更多信息,我们将添加其他一些小节。 -`Cargo.toml` 的最后一行,`[dependencies]`,是要列出项目全部依赖小节开始的地方。在 Rust 中,代码包被称为 *包裹(crates)*。此项目无需任何其他包裹,在第 2 章中的头一个项目,就会用到依赖包裹,因此在那时就会用到这个依赖小节。 +接下来的三行,设置了 Cargo 编译咱们程序所需的一些配置信息:程序名字、版本,以及要使用的 Rust 版本。关于 `edition` 这个关键字,我们将在 [附录 E](../appendix/editions.md) 中讨论。 -现在打开 `src/main.rs` 然后看看: +最后一行,`[dependencies]`(依赖项),是供咱们列出咱们项目全部依赖项的一个小节的开头。在 Rust 中,代码包被称为 *代码箱,crates*。而在本项目中,我们不会需要任何其他代码箱,不过在第 2 章的首个项目中,我们就会用到,因此届时我们将用到这个依赖项小节。 + +现在打开 `src/main.rs` 看看: 文件名:`src/main.rs` diff --git a/src/getting_started/hello_world.md b/src/getting_started/hello_world.md index 77f8933..5b1839f 100644 --- a/src/getting_started/hello_world.md +++ b/src/getting_started/hello_world.md @@ -87,7 +87,7 @@ Hello, World! **Anatomy of a Rust Program** -来仔细回顾一下刚才在 “Hello World!” 程序中发生了什么。这是谜团中第一部分: +咱们来详细回顾一下这个 "Hello, World!" 程序。下面是谜团的第一部分: ```rust fn main() { @@ -95,49 +95,54 @@ fn main() { } ``` -这些行定义了 Rust 中的一个函数。这个 `main` 函数比较特殊:在每个可执行的 Rust 程序中,他总是第一个开始运行的代码。这第一行声明了一个名为 `main` 的、没有参数且不返回任何值的参数。若函数有参数,那么参数就应位处圆括号`()`内部。 +这些行定义了一个名为 `main` 的函数。`main` 函数很特别:他总是每个可执行 Rust 程序中,运行的第一段代码。这里,其中第一行,声明了一个没有参数,也不返回任何内容的名为 `main` 的函数。如果有参数,则会放在括号 `()` 内。 -还有就是,请注意函数体是包裹在花括号`{}`中的。Rust 要求将全部函数体都用花括号包裹起来。将开头的花括号与函数声明放在同一行,并在二者之间加上一个空格,是良好的代码风格。 +函数体被包裹在 `{}` 中。Rust 要求,在所有函数体周围使用大括号。将开头的大括号,与函数声明放在同一行,在二者之间添加一个空格,是一种良好的编码风格。 -若想要在多个 Rust 项目之间保持一种标准的编码风格,那么就可以使用一个名为 `rustfmt` 的自动格式化工具,来以一种特定样式对代码进行格式化。与 `rustc` 一样,Rust 团队已将此工具包含在标准的 Rust 发布中,因此在你的电脑上就应该已经有了这个格式化工具了!请查看在线文档了解更多详情。 +> **注意**:如果咱们想在不同的 Rust 项目间,坚持使用某种标准的风格,咱们可以使用一个名为 `rustfmt` 的自动格式化工具,以某种特定风格,格式化咱们的代码(关于 `rustfmt` 的更多信息,请参见 [附录 D](../appendix/dev_tools.md))。如同 `rustc` 一样,Rust 团队已将这个工具,包含在了标准 Rust 发布中,因此他应该已安装在咱们的电脑上了! -在这个`main` 函数里头,是下面的代码: +`main` 函数的主体,包含以下代码: ```rust println!("Hello, World!"); ``` -这行代码完成了此小程序的全部工作:他将文字打印到屏幕。这里有四个需要注意的重要细节。 +这行代码,完成了这个小型程序的所有工作:将文本打印到屏幕上。这里有四个重要细节要注意。 -首先,Rust 编码风格是缩进四个空格,而非一个制表符; - -其次,`println!` 调用了一个 Rust 的宏(a Rust macro)。若他调用的是个函数,那么就应输入 `println` (是不带 `!` 的)。在后续的第 19 章,将详细讨论 Rust 的宏。而现在,则只需知道 `!` 的使用表示是在调用某个宏而不是普通函数,同时宏不会总是遵循与函数同样的规则; - -第三,就是看到的 `Hello, World!` 这个字符串了。这里时将此字符串作为参数,传递给 `println!` 的,且这个字符串是被打印到屏幕上的; - -最后,这行语句是以分号(`;`)结束的,这表示该表达式结束,同时下一表达式已准备好开始。Rust 代码的多数行,都是以分号结束的。 +首先,Rust 的编码风格,是缩进四个空格,而非一个制表符; -## 编译和运行是分开的步骤 +其次,`println!` 调用了一个 Rust 宏。如果他调用的是个函数,就会以 `println` 的形式输入(不带 `!`)。 我们将在第 19 章,详细讨论 Rust 的宏。现在,咱们只需知道,使用 `!` 表示咱们调用的是宏,而不是普通函数,而且宏并不总会遵循,与函数相同的规则。 -这里刚刚运行了一个新近创建出的程序,那么来检视一下该过程的每个步骤。 +第三,咱们会看到那个 "Hello, world!" 字符串。我们将该字符串作为参数,传递给了 `println!`; -在运行某个 Rust 程序之前,必须要通过敲入 `rustc` 命令并将源代码文件名字,作为`rustc`的参数加以传入,这样来使用 Rust 编译器对其进行编译,像下面这样: +最后,我们以表示此表达式结束,下个表达式准备开始的分号(`;`),结束了这行。Rust 代码的大多数行,都会以分号结束。 + + +## 编译和运行是两个独立的步骤 + +**Compiling and Running Are Separate Steps** + + +咱们刚刚运行了一个新进创建出的程序,那么就来监视一下,这个过程的每个步骤。 + +运行某个 Rust 程序之前,咱们必须通过输入 `rustc` 命令,并将源文件的名字传给他,而使用 Rust 的编译器编译他,就像这样: ```console $ rustc main.rs ``` -若你有 C 或 C++ 的背景知识,那么就会注意到这与 `gcc` 或 `clang` 类似。在成功编译后,Rust 就会输出一个二进制可执行文件。 +如果你有 C 或 C++ 背景,就会发现这与 `gcc` 或 `clang` 类似。编译成功后,Rust 会输出二进制可执行文件。 + +在 Linux、macOS 以及 Windows 的 PowerShell 中,咱们可以在咱们的 shell 中,输入 `ls` 命令看到这个可执行文件: -在 Linux、macOS 和 Windows 上的 PowerShell 之上,就可以通过在 `shell` 中敲入 `ls` 看到这个可执行文件。在 Linux 与 macOS 上,将看到下面这两个文件。而在 Windows 上的 PowerShell 中,则会看到与使用 CMD 一样的以下三个文件。 ```console $ ls main main.rs ``` -在 Windows 的 CMD 中,就应输入下面的东西: +在 Linux 和 macOS 上,咱们将看到两个文件。而在 Windows 上的 PowerShell 中,咱们将看到与使用 CMD 相同的三个文件。在 Windows 上的 CMD 中,咱们可以输入以下内容: ```console > dir /B %= 这里的 /B 选项表示只显示文件名 =% @@ -146,14 +151,14 @@ main.pdb main.rs ``` -这显示了带有 `.rs` 扩展名的源代码文件、那个可执行文件(Windows 上的 `main.exe`,对于其他平台则是 `main`),以及,在使用 Windows 时,一个包含了调试信息的、带有 `.pdb` 扩展名的文件。从此处,就像下面这样来运行这里的 `main` 或 `main.exe`: +这显示了扩展名为 `.rs` 的源代码文件、可执行文件(Windows 上为 `main.exe`,而在所有其他平台上为 `main`),以及使用 Windows 时,一个扩展名为 `.pdb`,包含着调试信息的文件。从这里,咱们运行那个 `main` 或 `main.exe` 文件,如下所示: + ```console $ ./main # 或在 Windows 上的 .\main.exe ``` +如果咱们的 `main.rs`,是那个 "Hello, world!" 程序,那么这行就会将 `Hello, world!` 打印到终端。 -若这里的 `main.rs` 就是那个 “Hello, World!” 程序,那么这行命令就会将 `Hello, World!` 打印到你的终端了。 +如果咱们更熟悉 Ruby、Python 或 JavaScript 等某门动态语言,则可能不习惯于将编译和运行某个程序,作为单独的步骤。Rust 属于一门 *提前编译,ahead-of-time compiled* 语言,这意味着,你能够编译某个程序,并把可执行文件交给其他人,而即使他们没有安装 Rust,也可以运行这个可执行程序。而如果咱们给别人某个 `.rb`、`.py` 或 `.js` 文件,他们就需要分别安装 Ruby、Python 或 JavaScript 的某种实现。不过在这些语言中,咱们只需要一条命令,来编译并运行咱们的程序。在语言设计中,一切都需要权衡利弊,everything is a trade-off in language design。 -若你对某门动态语言,诸如 Ruby、Python 或者 JavaScript 更为熟悉,那么可能就不习惯于将编译和运行某个程序作为分开的步骤。Rust 是门 *提前编译* 语言(an *ahead-of-time compiled* language),这意味着可对程序进行编译,而将可执行文件交给他人,他们可在未安装 Rust 的情况下运行编译好的可执行文件。而若将某个 `.rb`、`.py`,或者 `.js` 文件交给某人时,他们就需要安装好相应的 Ruby、Python 或 JavaScript 实现。不过在这些语言中,仅需一个命令来编译和运行他们的程序。在编程语言设计中,每件事都有所取舍。 - - 对于简单的程序来说,用 `rustc` 编译就足够了,但随着项目的成长,就希望对所有选项进行管理,并令到代码分享更为简便。接下来,就要介绍 Cargo 工具了,这工具将帮助我们编写出实用的 Rust 程序。 +对于简单程序,使用 `rustc` 编译就可以了,但随着项目的发展,咱们会希望管理所有选项,以及并方便共用咱们的代码。接下来,我们将介绍,将会帮助咱们编写真实世界 Rust 程序的 Cargo 工具。