diff --git a/src/ch00-00-introduction.md b/src/ch00-00-introduction.md index f7a7106..3de3acf 100644 --- a/src/ch00-00-introduction.md +++ b/src/ch00-00-introduction.md @@ -56,11 +56,11 @@ Rust 语言也希望能支持很多其他用户,这里提及的只是最大的 你会在本书中发现两类章节:概念章节和项目章节。在概念章节中,我们学习 Rust 的某个方面。在项目章节中,我们应用目前所学的知识一同构建小的程序。第二、十二和二十章是项目章节;其余都是概念章节。 -第一章介绍如何安装 Rust,如何编写 Hello, world! 程序,以及如何使用 Rust 的包管理器和构建工具 Cargo。第二章是 Rust 语言的实战介绍。我们会站在较高的层次介绍一些的概念,在稍后的章节种会做详细介绍。如果你希望立刻就动手实践一下,第二章正好适合你。开始阅读时,你甚至可能希望略过第三章,它介绍了 Rust 中类似其他编程语言中的功能,并直接阅读第四章学习 Rust 的所有权系统。然而,如果你是特别重视细节的学习者,并倾向于在继续之前学习每一个细节,你可能希望略过第二章并直接阅读第三章,并在想要构建项目来实践这些细节时再回来阅读第二章。 +第一章介绍如何安装 Rust,如何编写 “Hello, world!” 程序,以及如何使用 Rust 的包管理器和构建工具 Cargo。第二章是 Rust 语言的实战介绍。我们会站在较高的层次介绍一些的概念,在稍后的章节种会做详细介绍。如果你希望立刻就动手实践一下,第二章正好适合你。开始阅读时,你甚至可能希望略过第三章,它介绍了 Rust 中类似其他编程语言中的功能,并直接阅读第四章学习 Rust 的所有权系统。然而,如果你是特别重视细节的学习者,并倾向于在继续之前学习每一个细节,你可能希望略过第二章并直接阅读第三章,并在想要构建项目来实践这些细节时再回来阅读第二章。 第五章讨论结构体和方法,第六章介绍枚举、`match` 表达式和 `if let` 控制流结构。在 Rust 中,你将使用结构体和枚举创建自定义类型。 -第七章,你会学习 Rust 的模块系统和私有性规则来组织代码和公有应用程序接口(Application Programming Interface, API)。第八章讨论了一些标准库提供的常见集合数据结构,比如 vector、字符串和哈希 map。第九章探索了 Rust 的错误处理哲学和技术。 +第七章你会学习 Rust 的模块系统和私有性规则来组织代码和公有应用程序接口(Application Programming Interface, API)。第八章讨论了一些标准库提供的常见集合数据结构,比如 vector、字符串和哈希 map。第九章探索了 Rust 的错误处理哲学和技术。 第十章深入介绍泛型、trait 和生命周期,他们提供了定义出适用于多种类型的代码的能力。第十一章全部关于测试,即使 Rust 有安全保证,也需要测试确保程序逻辑正确。第十二章,我们构建了属于自己的在文件中搜索文本的命令行工具 `grep` 的子集功能实现。为此会利用之前章节讨论的很多概念。 diff --git a/src/ch01-01-installation.md b/src/ch01-01-installation.md index 50efcba..5058250 100644 --- a/src/ch01-01-installation.md +++ b/src/ch01-01-installation.md @@ -2,7 +2,7 @@ > [ch01-01-installation.md](https://github.com/rust-lang/book/blob/master/src/ch01-01-installation.md) >
-> commit 1fedfc4b96c2017f64ecfcf41a0a07e2e815f24f +> commit 27e741b227b6b946a1498ecc9d9dd1bff5819b82 第一步是安装 Rust。我们通过 `rustup` 下载 Rust,这是一个管理 Rust 版本和相关工具的命令行工具。下载时需要联网。 @@ -28,7 +28,7 @@ $ curl https://sh.rustup.rs -sSf | sh Rust is installed now. Great! ``` -如果你愿意,可在运行前下载并检查该脚本。 +如果你愿意的话,可在运行前下载并检查该脚本。 此安装脚本自动将 Rust 加入系统 PATH 环境变量中,在下一次登录时生效。如果你希望立刻就开始使用 Rust 而不重启终端,在 shell 中运行如下命令,手动将 Rust 加入系统 PATH 变量中: @@ -48,7 +48,7 @@ $ export PATH="$HOME/.cargo/bin:$PATH" 在 Windows 上,前往 [https://www.rust-lang.org/install.html][install] 并按照说明安装 Rust。在安装过程的某个步骤,你会收到一个信息说明为什么需要安装 Visual Studio 2013 或更新版本的 C++ build tools。获取这些 build tools 最方便的方法是安装 [Build Tools for Visual Studio 2019][visualstudio]。这个工具在 “Other Tools and Frameworks” 部分。 -[install]: https://www.rust-lang.org/install.html +[install]: https://www.rust-lang.org/tools/install [visualstudio]: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019 本书的余下部分会使用能同时运行于 *cmd.exe* 和 PowerShell 的命令。如果存在特定差异,我们会解释使用哪一个。 @@ -81,10 +81,9 @@ $ rustc --version rustc x.y.z (abcabcabc yyyy-mm-dd) ``` -如果出现这些内容,Rust 就安装成功了!如果并没有看到这些信息,并且使用的是 Windows,请检查 Rust 是否位于 `%PATH%` 系统变量中。如果一切正确但 Rust 仍不能使用,有许多地方可以求助。最简单的是 [irc.mozilla.org 上的 #rust IRC 频道][irc] ,可以使用 [Mibbit][mibbit] 来访问它。然后就能和其他 Rustacean(Rust 用户的称号,有自嘲意味)聊天并寻求帮助。其它给力的资源包括[用户论坛][users]和 [Stack Overflow][stackoverflow]。 +如果出现这些内容,Rust 就安装成功了!如果并没有看到这些信息,并且使用的是 Windows,请检查 Rust 是否位于 `%PATH%` 系统变量中。如果一切正确但 Rust 仍不能使用,有许多地方可以求助。最简单的是 [位于 Rust 官方 Discord][discord] 上的 #beginners 频道。在这里你可以和其他 Rustacean(Rust 用户的称号,有自嘲意味)聊天并寻求帮助。其它给力的资源包括[用户论坛][users]和 [Stack Overflow][stackoverflow]。 -[irc]: irc://irc.mozilla.org/#rust -[mibbit]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust +[discord]: https://discord.gg/rust-lang [users]: https://users.rust-lang.org/ [stackoverflow]: http://stackoverflow.com/questions/tagged/rust diff --git a/src/ch01-02-hello-world.md b/src/ch01-02-hello-world.md index f7aebf8..66b1db5 100644 --- a/src/ch01-02-hello-world.md +++ b/src/ch01-02-hello-world.md @@ -2,7 +2,7 @@ > [ch01-02-hello-world.md](https://github.com/rust-lang/book/blob/master/src/ch01-02-hello-world.md) >
-> commit 1fedfc4b96c2017f64ecfcf41a0a07e2e815f24f +> commit f63a103270ec8416899675a9cdb1c5cf6d77a498 既然安装好了 Rust,我们来编写第一个 Rust 程序。当学习一门新语言的时候,使用该语言在屏幕上打印 `Hello, world!` 是一项传统,我们将沿用这一传统! @@ -12,9 +12,9 @@ 首先创建一个存放 Rust 代码的目录。Rust 并不关心代码的存放位置,不过对于本书的练习和项目来说,我们建议你在 home 目录中创建 *projects* 目录,并将你的所有项目存放在这里。 -打开终端并输入如下命令创建 *projects* 目录,并在 *projects* 目录中为 Hello, world! 项目创建一个目录。 +打开终端并输入如下命令创建 *projects* 目录,并在 *projects* 目录中为 “Hello, world!” 项目创建一个目录。 -对于 Linux 和 macOS,输入: +对于 Linux、macOS 和 Windows PowerShell,输入: ```text $ mkdir ~/projects @@ -32,15 +32,6 @@ $ cd hello_world > cd hello_world ``` -对于 Windows PowerShell,输入: - -```powershell -> mkdir $env:USERPROFILE\projects -> cd $env:USERPROFILE\projects -> mkdir hello_world -> cd hello_world -``` - ### 编写并运行 Rust 程序 接下来,新建一个源文件,命名为 *main.rs*。Rust 源文件总是以 *.rs* 扩展名结尾。如果文件名包含多个单词,使用下划线分隔它们。例如命名为 *hello_world.rs*,而不是 *helloworld.rs*。 @@ -73,13 +64,13 @@ Hello, world! Hello, world! ``` -不管使用何种操作系统,终端应该打印字符串 `Hello, world!`。如果没有看到这些输出,回到 “故障排除” 部分查找寻求帮助的方法。 +不管使用何种操作系统,终端应该打印字符串 `Hello, world!`。如果没有看到这些输出,回到安装部分的 [“故障排除”][troubleshooting] 小节查找有帮助的方法。 如果 `Hello, world!` 出现了,恭喜你!你已经正式编写了一个 Rust 程序。现在你成为一名 Rust 程序员,欢迎! -### 分析 Rust 程序 +### 分析这个 Rust 程序 -现在,让我们回过头来仔细看看 Hello, world! 程序中到底发生了什么。这是第一块拼图: +现在,让我们回过头来仔细看看 “Hello, world!” 程序中到底发生了什么。这是第一块拼图: ```rust fn main() { @@ -119,26 +110,17 @@ $ rustc main.rs 如果你有 C 或 C++ 背景,就会发现这与 `gcc` 和 `clang` 类似。编译成功后,Rust 会输出一个二进制的可执行文件。 -在 Linux、macOS 或 Windows 的 PowerShell 上,在 shell 中输入 `ls` 命令也可以看见这个可执行文件,如下: +在 Linux、macOS 或 Windows 的 PowerShell 上,在 shell 中输入 `ls` 命令可以看见这个可执行文件。在 Linux 和 macOS,你会看到两个文件。在 Windows PowerShell 中,你会看到同使用 CMD 相同的三个文件。 ```text -> ls - - - Directory: Path:\to\the\project - - -Mode LastWriteTime Length Name ----- ------------- ------ ---- --a---- 6/1/2018 7:31 AM 137728 main.exe --a---- 6/1/2018 7:31 AM 1454080 main.pdb --a---- 6/1/2018 7:31 AM 14 main.rs +$ ls +main main.rs ``` 在 Windows 的 CMD 上,则输入如下内容: ```cmd -> dir /B %= /B 参数表示只显示文件名 =% +> dir /B %= the /B option says to only show the file names =% main.exe main.pdb main.rs @@ -150,8 +132,10 @@ main.rs $ ./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 实现(运行时环境,VM)。不过在这些语言中,只需要一句命令就可以编译和运行程序。这一切都是语言设计上的权衡取舍。 仅仅使用 `rustc` 编译简单程序是没问题的,不过随着项目的增长,你可能需要管理你项目的方方面面,并让代码易于分享。接下来,我们要介绍一个叫做 Cargo 的工具,它会帮助你编写真实世界中的 Rust 程序。 + +[troubleshooting]: ch01-01-installation.html#troubleshooting \ No newline at end of file diff --git a/src/ch01-03-hello-cargo.md b/src/ch01-03-hello-cargo.md index 3780cf9..551af37 100644 --- a/src/ch01-03-hello-cargo.md +++ b/src/ch01-03-hello-cargo.md @@ -2,13 +2,13 @@ > [ch01-03-hello-cargo.md](https://github.com/rust-lang/book/blob/master/src/ch01-03-hello-cargo.md) >
-> commit 7ccf60ad3b85e06ad0a2cb7c422dc80c42ecc963 +> commit f63a103270ec8416899675a9cdb1c5cf6d77a498 Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库。(我们把代码所需要的库叫做 **依赖**(*dependencies*))。 -最简单的 Rust 程序,比如我们刚刚编写的,没有任何依赖。所以如果使用 Cargo 来构建 Hello, world! 项目,将只会用到 Cargo 构建代码的那部分功能。在编写更复杂的Rust程序时,你将添加依赖项,如果使用Cargo启动项目,则添加依赖项将更容易。 +最简单的 Rust 程序,比如我们刚刚编写的,没有任何依赖。所以如果使用 Cargo 来构建 “Hello, world!” 项目,将只会用到 Cargo 构建代码的那部分功能。在编写更复杂的 Rust 程序时,你将添加依赖项,如果使用 Cargo 启动项目,则添加依赖项将更容易。 -由于绝大多数 Rust 项目使用 Cargo,本书接下来的部分假设你也使用 Cargo。如果使用 “安装” 部分介绍的官方安装包的话,则自带了 Cargo。如果通过其他方式安装的话,可以在终端输入如下命令检查是否安装了 Cargo: +由于绝大多数 Rust 项目使用 Cargo,本书接下来的部分假设你也使用 Cargo。如果使用 [“安装”][installation] 部分介绍的官方安装包的话,则自带了 Cargo。如果通过其他方式安装的话,可以在终端输入如下命令检查是否安装了 Cargo: ```text $ cargo --version @@ -53,7 +53,7 @@ edition = "2018" 第一行,`[package]`,是一个片段(section)标题,表明下面的语句用来配置一个包。随着我们在这个文件增加更多的信息,还将增加其他片段(section)。 -接下来的四行设置了 Cargo 编译程序所需的配置:项目的名称、版本、作者以及要使用的Rust版本。Cargo 从环境中获取你的名字和 email 信息,所以如果这些信息不正确,请修改并保存此文件。附录 E 会介绍 `edition` 的值。 +接下来的四行设置了 Cargo 编译程序所需的配置:项目的名称、版本、作者以及要使用的 Rust 版本。Cargo 从环境中获取你的名字和 email 信息,所以如果这些信息不正确,请修改并保存此文件。附录 E 会介绍 `edition` 的值。 最后一行,`[dependencies]`,是罗列项目依赖的片段的开始。在 Rust 中,代码包被称为 *crates*。这个项目并不需要其他的 crate,不过在第二章的第一个项目会用到依赖,那时会用得上这个片段。 @@ -67,15 +67,15 @@ fn main() { } ``` -Cargo 为你生成了一个 Hello World! 程序,正如我们之前编写的示例 1-1!目前为止,之前项目与 Cargo 生成项目的区别是 Cargo 将代码放在 *src* 目录,同时项目根目录包含一个 *Cargo.toml* 配置文件。 +Cargo 为你生成了一个 “Hello, world!” 程序,正如我们之前编写的示例 1-1!目前为止,之前项目与 Cargo 生成项目的区别是 Cargo 将代码放在 *src* 目录,同时项目根目录包含一个 *Cargo.toml* 配置文件。 Cargo 期望源文件存放在 *src* 目录中。项目根目录只存放 README、license 信息、配置文件和其他跟代码无关的文件。使用 Cargo 帮助你保持项目干净整洁,一切井井有条。 -如果没有用 Cargo 开始项目,比如我们创建的 Hello,world! 项目,可以将其转化为一个 Cargo 项目。将代码放入 *src* 目录,并创建一个合适的 *Cargo.toml* 文件。 +如果没有使用 Cargo 开始项目,比如我们创建的 Hello,world! 项目,可以将其转化为一个 Cargo 项目。将代码放入 *src* 目录,并创建一个合适的 *Cargo.toml* 文件。 ### 构建并运行 Cargo 项目 -现在让我们看看通过 Cargo 构建和运行 Hello, world! 程序有什么不同!在 *hello_cargo* 目录下,输入下面的命令来构建项目: +现在让我们看看通过 Cargo 构建和运行 “Hello, world!” 程序有什么不同!在 *hello_cargo* 目录下,输入下面的命令来构建项目: ```text $ cargo build @@ -160,3 +160,5 @@ $ cargo build * 使用 Cargo 创建并运行新项目 是时候通过构建更实质性的程序来熟悉读写 Rust 代码了。所以在第二章我们会构建一个猜猜看游戏程序。如果你更愿意从学习 Rust 常用的编程概念开始,请阅读第三章,接着再回到第二章。 + +[installation]: ch01-01-installation.html#installation \ No newline at end of file diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 17cf30c..ca55310 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -2,7 +2,7 @@ > [ch02-00-guessing-game-tutorial.md](https://github.com/rust-lang/book/blob/master/src/ch02-00-guessing-game-tutorial.md) >
-> commit 6d3e76820418f2d2bb203233c61d90390b5690f1 +> commit c427a676393d001edc82f1a54a3b8026abcf9690 让我们一起动手完成一个项目,来快速上手 Rust!本章将介绍 Rust 中一些常用概念,并通过真实的程序来展示如何运用它们。你将会学到 `let`、`match`、方法、关联函数、外部 crate 等知识!后续章节会深入探讨这些概念的细节。在这一章,我们将做基础练习。 @@ -126,7 +126,7 @@ let mut guess = String::new(); let foo = bar; ``` -这行代码新建了一个叫做 `foo` 的变量并把它绑定到值 `bar` 上。在 Rust 中,变量默认是不可变的。我们将会在第三章的 “变量与可变性” 部分详细讨论这个概念。下面的例子展示了如何在变量名前使用 `mut` 来使一个变量可变: +这行代码新建了一个叫做 `foo` 的变量并把它绑定到值 `bar` 上。在 Rust 中,变量默认是不可变的。我们将会在第三章的 [“变量与可变性”][variables-and-mutability] 部分详细讨论这个概念。下面的例子展示了如何在变量名前使用 `mut` 来使一个变量可变: ```rust,ignore let foo = 5; // 不可变 @@ -351,7 +351,7 @@ rand = "0.6.0" ### 生成一个随机数 -你已经把 `rand` crate 添加到 *Cargo.toml* 了,让我们开始 **使用** `rand` 吧。下一步是更新 *src/main.rs*,如示例 2-3 所示。 +你已经把 `rand` crate 添加到 *Cargo.toml* 了,让我们开始使用 `rand`。下一步是更新 *src/main.rs*,如示例 2-3 所示。 文件名: src/main.rs @@ -456,7 +456,7 @@ error[E0308]: mismatched types --> src/main.rs:23:21 | 23 | match guess.cmp(&secret_number) { - | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integral variable + | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integer | = note: expected type `&std::string::String` = note: found type `&{integer}` @@ -507,7 +507,7 @@ let guess: u32 = guess.trim().parse() [parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse -`parse` 调用很容易产生错误。例如,字符串中包含 `A👍%`,就无法将其转换为一个数字。因此,`parse` 方法返回一个 `Result` 类型。像之前 “使用 `Result` 类型来处理潜在的错误” 讨论的 `read_line` 方法那样,再次按部就班的用 `expect` 方法处理即可。如果 `parse` 不能从字符串生成一个数字,返回一个 `Result` 的 `Err` 成员时,`expect` 会使游戏崩溃并打印附带的信息。如果 `parse` 成功地将字符串转换为一个数字,它会返回 `Result` 的 `Ok` 成员,然后 `expect` 会返回 `Ok` 值中的数字。 +`parse` 调用很容易产生错误。例如,字符串中包含 `A👍%`,就无法将其转换为一个数字。因此,`parse` 方法返回一个 `Result` 类型。像之前 [“使用 `Result` 类型来处理潜在的错误”](#handling-potential-failure-with-the-result-type) 讨论的 `read_line` 方法那样,再次按部就班的用 `expect` 方法处理即可。如果 `parse` 不能从字符串生成一个数字,返回一个 `Result` 的 `Err` 成员时,`expect` 会使游戏崩溃并打印附带的信息。如果 `parse` 成功地将字符串转换为一个数字,它会返回 `Result` 的 `Ok` 成员,然后 `expect` 会返回 `Ok` 值中的数字。 现在让我们运行程序! @@ -555,7 +555,7 @@ Too big! 如上所示,我们将提示用户猜测之后的所有内容放入了循环。确保 loop 循环中的代码多缩进四个空格,再次运行程序。注意这里有一个新问题,因为程序忠实地执行了我们的要求:永远地请求另一个猜测,用户好像无法退出啊! -用户总能使用 ctrl-c 终止程序。不过还有另一个方法跳出无限循环,就是 “比较猜测与秘密数字” 部分提到的 `parse`:如果用户输入的答案不是一个数字,程序会崩溃。用户可以利用这一点来退出,如下所示: +用户总能使用 ctrl-c 终止程序。不过还有另一个方法跳出无限循环,就是 [“比较猜测与秘密数字”](#comparing-the-guess-to-the-secret-number) 部分提到的 `parse`:如果用户输入的答案不是一个数字,程序会崩溃。用户可以利用这一点来退出,如下所示: ```text $ cargo run @@ -587,7 +587,7 @@ error: Process didn't exit successfully: `target/debug/guess` (exit code: 101) ### 猜测正确后退出 -让我们增加一个 `break`,在用户猜对时退出游戏: +让我们增加一个 `break` 语句,在用户猜对时退出游戏: 文件名: src/main.rs @@ -710,3 +710,6 @@ fn main() { 此时此刻,你顺利完成了猜猜看游戏。恭喜! 本项目通过动手实践,向你介绍了 Rust 新概念:`let`、`match`、方法、关联函数、使用外部 crate 等等,接下来的几章,你会继续深入学习这些概念。第三章介绍大部分编程语言都有的概念,比如变量、数据类型和函数,以及如何在 Rust 中使用它们。第四章探索所有权(ownership),这是一个 Rust 同其他语言大不相同的功能。第五章讨论结构体和方法的语法,而第六章侧重解释枚举。 + +[variables-and-mutability]: +ch03-01-variables-and-mutability.html#variables-and-mutability \ No newline at end of file diff --git a/src/foreword.md b/src/foreword.md index 78d096b..d448ba9 100644 --- a/src/foreword.md +++ b/src/foreword.md @@ -1,8 +1,8 @@ # 前言 -> [foreword.md](https://github.com/rust-lang/book/blob/master/second-edition/src/foreword.md) +> [foreword.md](https://github.com/rust-lang/book/blob/master/src/foreword.md) >
-> commit 5e085bd1add34aec03416e891751552b439dde52 +> commit 1fedfc4b96c2017f64ecfcf41a0a07e2e815f24f 虽然不是那么明显,但 Rust 程序设计语言的本质在于 **赋能**(*empowerment*):无论你现在编写的是何种代码,Rust 能让你在更为广泛的编程领域走得更远,写出自信。