mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2026-08-19 12:43:28 +08:00
Compare commits
22 Commits
v1.0.0-202
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a72d87b31 | ||
|
|
528e5e910f | ||
|
|
943fe80acd | ||
|
|
dd0bf507c8 | ||
|
|
7f7897302f | ||
|
|
975f724980 | ||
|
|
0baca128d7 | ||
|
|
2b842de9dd | ||
|
|
5c94a6d873 | ||
|
|
b6efffe1d8 | ||
|
|
2fdce107c2 | ||
|
|
a5c3c0e34e | ||
|
|
2f9f853b27 | ||
|
|
7185782396 | ||
|
|
7b38e173d9 | ||
|
|
e4b0dba808 | ||
|
|
887e54f63a | ||
|
|
c712c8df2e | ||
|
|
2ce3afa0bc | ||
|
|
0c5136d929 | ||
|
|
a0f1e108b1 | ||
|
|
0aeb8a244f |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -4,3 +4,8 @@ Cargo.lock
|
||||
/index.html
|
||||
*.tar.gz
|
||||
pdf
|
||||
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
|
||||
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "rust-lang-zh_CN"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
@@ -16,7 +16,7 @@ rustc 1.93.1 (01f6ddf75 2026-02-11)
|
||||
|
||||
在线阅读: [rust-lang.xfoss.com](https://rust-lang.xfoss.com)
|
||||
|
||||
本地阅读:[`mdbook` 本地运行](./local_serving.md)
|
||||
本地阅读:[`mdbook` 本地运行](./src/local_serving.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -30,7 +30,7 @@ rustc 1.93.1 (01f6ddf75 2026-02-11)
|
||||
|
||||
已在进行底层代码编写的程序员们,可运用 Rust 来托起他们的雄心壮志。比如说,在 Rust 中引入并行机制,是相对低风险的手法:编译器会为咱们捕获经典错误。同时咱们还可以在不会引入程序崩溃或漏洞利用下,自信地进行更激进的优化。
|
||||
|
||||
而 Rust 并不局限于底层的系统变成。对于构造命令行应用、web 服务器及其他类别的代码来说,它的表现力和人体工程学足以使命令行界面的,Command-Line Interface,CLI,应用程序、Web 服务器和许多其他类型的代码编写得相当愉快 -- 你会在本书后面找到这两种代码的简单例子。使用 Rust 可以让咱们构建出从一个领域迁移到另一领域的技能;咱们可以通过编写 Web 应用来学习 Rust,然后把这些相同的技能应用在咱们的 Raspberry Pi 上。
|
||||
而 Rust 并不局限于底层的系统编程。对于构造命令行应用、web 服务器及其他类别的代码来说,它的表现力和人体工程学足以使命令行界面的,Command-Line Interface,CLI,应用程序、Web 服务器和许多其他类型的代码编写得相当愉快 -- 你会在本书后面找到这两种代码的简单例子。使用 Rust 可以让咱们构建出从一个领域迁移到另一领域的技能;咱们可以通过编写 Web 应用来学习 Rust,然后把这些相同的技能应用在咱们的 Raspberry Pi 上。
|
||||
|
||||
本书充分体现了 Rust 在增强用户能力方面的潜力。这是一本友好且平易近人的教材,旨在帮助咱们不仅提高咱们的 Rust 知识水平,并提高咱们作为一名普通程序员的触及范围和信心。那么,请投入其中,准备学习,并欢迎加入 Rust 社区!
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ language = "zh"
|
||||
src = "src"
|
||||
title = "Yet another Chinese rust-lang book."
|
||||
description = "又一本 rust-lang 书,Yet another Chinese rust-lang book。"
|
||||
mdbook_version = "0.4.29"
|
||||
|
||||
[preprocessor.last-changed]
|
||||
command = "mdbook-last-changed"
|
||||
|
||||
@@ -30,7 +30,7 @@ rustc 1.93.1 (01f6ddf75 2026-02-11)
|
||||
|
||||
已在进行底层代码编写的程序员们,可运用 Rust 来托起他们的雄心壮志。比如说,在 Rust 中引入并行机制,是相对低风险的手法:编译器会为咱们捕获经典错误。同时咱们还可以在不会引入程序崩溃或漏洞利用下,自信地进行更激进的优化。
|
||||
|
||||
而 Rust 并不局限于底层的系统变成。对于构造命令行应用、web 服务器及其他类别的代码来说,它的表现力和人体工程学足以使命令行界面的,Command-Line Interface,CLI,应用程序、Web 服务器和许多其他类型的代码编写得相当愉快 -- 你会在本书后面找到这两种代码的简单例子。使用 Rust 可以让咱们构建出从一个领域迁移到另一领域的技能;咱们可以通过编写 Web 应用来学习 Rust,然后把这些相同的技能应用在咱们的 Raspberry Pi 上。
|
||||
而 Rust 并不局限于底层的系统编程。对于构造命令行应用、web 服务器及其他类别的代码来说,它的表现力和人体工程学足以使命令行界面的,Command-Line Interface,CLI,应用程序、Web 服务器和许多其他类型的代码编写得相当愉快 -- 你会在本书后面找到这两种代码的简单例子。使用 Rust 可以让咱们构建出从一个领域迁移到另一领域的技能;咱们可以通过编写 Web 应用来学习 Rust,然后把这些相同的技能应用在咱们的 Raspberry Pi 上。
|
||||
|
||||
本书充分体现了 Rust 在增强用户能力方面的潜力。这是一本友好且平易近人的教材,旨在帮助咱们不仅提高咱们的 Rust 知识水平,并提高咱们作为一名普通程序员的触及范围和信心。那么,请投入其中,准备学习,并欢迎加入 Rust 社区!
|
||||
|
||||
@@ -115,12 +115,12 @@ Rust 语言希望也能支持许多其他用户;这里提到的只是一些最
|
||||
|
||||
[第 13 章](./Ch13_Functional_Language_Features_Iterators_and_Closures.md) 探讨了闭包和迭代器:来自于函数式编程语言的 Rust 特性。在 [第 14 章](./Ch14_More_about_Cargo_and_Crates-io.md) 中,我们将更深入地研究 Cargo,并讲到与他人共享库的最佳实践。[第 15 章](./Ch15_Smart_Pointers.md) 讨论了标准库提供的灵巧指针和实现其功能的特质。
|
||||
|
||||
[第 16 章](./Ch16_Fearless_Concurrency.md),咱们将过目不同的并发编程模型,并探讨 Rust 如何帮助咱们大胆地以多线程方式编程。在 [第 17 章](./Ch16_1_async_programming.md) 中,我们在此基础上探讨 Rust 的 `async` 与 `await` 语法,以及任务、未来值与流,以及他们所实现的轻量级并发模型。
|
||||
[第 16 章](./Ch16_Fearless_Concurrency.md),咱们将过目不同的并发编程模型,并探讨 Rust 如何帮助咱们大胆地以多线程方式编程。在 [第 17 章](./Ch17_async_programming.md) 中,我们在此基础上探讨 Rust 的 `async` 与 `await` 语法,以及任务、未来值与流,以及他们所实现的轻量级并发模型。
|
||||
|
||||
|
||||
[第 18 章](./Ch17_Object_Oriented_Programming_Features_of_Rust.md) 着眼于 Rust 习语如何与咱们可能熟悉的面向对象编程原则进行比较。[第 19 章](./Ch18_Patterns_and_Matching.md) 是关于模式和模式匹配的参考,他们是在整个 Rust 程序中表达思想的强大方式。[第 20 章](./Ch19_Advanced_Features.md) 包含大量有趣的高级主题,包括不安全的 Rust、宏,以及更多关于生命周期、特征、类型、函数和闭包的内容。
|
||||
[第 18 章](./Ch18_Object_Oriented_Programming_Features_of_Rust.md) 着眼于 Rust 习语如何与咱们可能熟悉的面向对象编程原则进行比较。[第 19 章](./Ch18_Patterns_and_Matching.md) 是关于模式和模式匹配的参考,他们是在整个 Rust 程序中表达思想的强大方式。[第 20 章](./Ch19_Advanced_Features.md) 包含大量有趣的高级主题,包括不安全的 Rust、宏,以及更多关于生命周期、特征、类型、函数和闭包的内容。
|
||||
|
||||
在 [第 21 章](./Ch20_Final_Project_Building_a_Multithreaded_Web_Server.md),咱们将完成其中实现了底层线程化 web 服务器的一个项目!
|
||||
在 [第 21 章](./Ch21_Final_Project_Building_a_Multithreaded_Web_Server.md),咱们将完成其中实现了底层线程化 web 服务器的一个项目!
|
||||
|
||||
最后,一些附录以更类似于参考的格式,包含有关这门语言的有用信息。[附录 A](./appendix/keywords.md) 涵盖了 Rust 的关键字,[附录 B](./appendix/ops_and_symbols.md) 涵盖了 Rust 的运算符和符号,[附录 C](./appendix/derivable_traits.md) 涵盖了标准库提供的可派生特质,[附录 D](./appendix/dev_tools.md) 涵盖了一些有用的开发工具,[附录 E](./appendix/editions.md) 解释了 Rust 版本。在 [附录 F](./appendix/translations.md) 中,你可以找到这本书的翻译,在 [附录 G](./appendix/releases.md) 中,我们将介绍 Rust 是如何构造的以及什么是每日 Rust, nightly Rust。
|
||||
|
||||
|
||||
@@ -171,8 +171,8 @@ fn main() {
|
||||
|
||||
|
||||
```rust
|
||||
io:stdin()
|
||||
.readline(&mut guess)
|
||||
io::stdin()
|
||||
.read_line(&mut guess)
|
||||
```
|
||||
|
||||
若我们没有在程序开头,以 `use std::io;` 导入 `io` 库,我们仍就可以通过将这一函数调用,写作 `std::io::stdin` 使用这个函数。`stdin` 函数会返回 [`std::io::Stdin`](https://doc.rust-lang.org/std/io/struct.Stdin.html) 的一个实例,而这是表示终端标准输入句柄的一种类型,a type that represents a handle to the standard input for your terminal。
|
||||
@@ -459,7 +459,7 @@ fn main() {
|
||||
|
||||
首先,我们要添加行 `use rand::Rng;`。`Rng` 这个特质定义了随机数生成器所实现的一些方法,而这个特质必须要在咱们要用到那些方法的作用域中。[第 10 章](./generic_types_traits_and_lifetimes/traits.md) 将详细介绍特质。
|
||||
|
||||
接下来,我们在中间添加了两行。在第一行中,我们调用了 `rand:thread_rng` 这个函数,他给到我们即将用到的特定随机数生成器,the particular random number generator:一个属于当前执行线程本地的,由操作系统提供种子的随机数生成器。然后,我们调用了这个随机数生成器上的 `gen_range` 方法。这个方法是由我们以 `use rand::Rng;` 语句,带入到作用域的 `Rng` 特质定义的。`gen_range` 方法会取一个范围表达式作为参数,生成该范围中的一个随机数。我们这里使用的范围表达式类别,采用了 `start..=end` 形式,并包含下上边界,因此我们需要指定 `1...=100`,请求一个 1 和 100 之间的数字。
|
||||
接下来,我们在中间添加了两行。在第一行中,我们调用了 `rand::thread_rng` 这个函数,他给到我们即将用到的特定随机数生成器,the particular random number generator:一个属于当前执行线程本地的,由操作系统提供种子的随机数生成器。然后,我们调用了这个随机数生成器上的 `gen_range` 方法。这个方法是由我们以 `use rand::Rng;` 语句,带入到作用域的 `Rng` 特质定义的。`gen_range` 方法会取一个范围表达式作为参数,生成该范围中的一个随机数。我们这里使用的范围表达式类别,采用了 `start..=end` 形式,并包含上下边界,因此我们需要指定 `1..=100`,请求一个 1 和 100 之间的数字。
|
||||
|
||||
|
||||
> **注意**:咱们不会凭空知道要使用哪个特质、调用某个代码箱中的哪些方法与函数,因此每个代码箱都有使用说明文档。Cargo 的另一巧妙特性便是,运行 `cargo doc --open` 命令就将在本地构建出有所有咱们依赖项所提供的文档,并在咱们浏览器中打开。例如,当咱们对 `rand` 代码箱中别的功能感兴趣时,那么就运行 `cargo doc --open`,并点击左侧边栏中的 `rand`。
|
||||
|
||||
@@ -16,6 +16,6 @@ Rust 社区成员 Andrew Gallant 已经创建了个特性完整、速度非常
|
||||
- 在适当情况下使用特质和生命周期([第 10 章](./Ch10_Generic_Types_Traits_and_Lifetimes.md))
|
||||
- 编写测试([第 11 章](./Ch11_Writing_Automated_Tests.md))
|
||||
|
||||
我们还将简要介绍闭包、迭代器与特质对象等,[第 13 章](./Ch13_Functional_Language_Features_Iterators_and_Closures.md) 与 [第 18 章](./Ch17_Object_Oriented_Programming_Features_of_Rust.md) 将详细介绍他们。
|
||||
我们还将简要介绍闭包、迭代器与特质对象等,[第 13 章](./Ch13_Functional_Language_Features_Iterators_and_Closures.md) 与 [第 18 章](./Ch18_Object_Oriented_Programming_Features_of_Rust.md) 将详细介绍他们。
|
||||
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
| 符号 | 说明 |
|
||||
| :--- | :--- |
|
||||
| `#[meta]` | 外层属性 |
|
||||
| `#![meta]` | 内层熟悉 |
|
||||
| `#![meta]` | 内层属性 |
|
||||
| `$ident` | 宏代换 |
|
||||
| `$ident:kind` | 宏的元变量 |
|
||||
| `$(...) ...` | 宏的重复 |
|
||||
|
||||
@@ -74,7 +74,7 @@ stable: *
|
||||
|
||||
Rust 每六周发布一次,就像时刻表一样。当咱们知道某次 Rust 发布的日期,就可以知道下一发布的日期:那就是六周后。每六周安排一次发布的一个好处是,下一班列车很快就会到来。若某项特性碰巧错过了某个特定发布,也无需担心:另一个发布很快就会出现!这有助于减少在发布截止日期邻近时,塞入可能尚未打磨完善的特性所带来的压力。
|
||||
|
||||
得益于这一流程,咱们可以岁时检出 Rust 的下一个构建,并请自验证是否可以轻松升级到该构建:当 beta 发布未如预期运行时,咱们可以向 Rust 团队报告而在下一个稳定发布之前修复他!beta 发布中的损坏相对较少,但 `rustc` 终究是个软件,因此确实存在一些 bug。
|
||||
得益于这一流程,咱们可以随时检出 Rust 的下一个构建,并请自验证是否可以轻松升级到该构建:当 beta 发布未如预期运行时,咱们可以向 Rust 团队报告而在下一个稳定发布之前修复他!beta 发布中的损坏相对较少,但 `rustc` 终究是个软件,因此确实存在一些 bug。
|
||||
|
||||
|
||||
## 维护周期
|
||||
|
||||
@@ -52,7 +52,7 @@ fn main() {
|
||||
|
||||
# 本章小结
|
||||
|
||||
这并不是咱们在这本书中最后一次看到并发。[第 21 章](../Ch20_Final_Project_Building_a_Multithreaded_Web_Server.md) 中的项目,将在比这里讨论的简单示例更贴近实际的情境下应用这些概念,并更直接地比较分别通过线程、任务和未来值解决问题。
|
||||
这并不是咱们在这本书中最后一次看到并发。[第 21 章](../Ch21_Final_Project_Building_a_Multithreaded_Web_Server.md) 中的项目,将在比这里讨论的简单示例更贴近实际的情境下应用这些概念,并更直接地比较分别通过线程、任务和未来值解决问题。
|
||||
|
||||
无论咱们选择哪种方法,Rust 都会给予咱们编写安全、高效、并发代码所需的工具 —— 无论是用于高吞吐量的 Web 服务器,还是嵌入式操作系统。
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ pub trait Future {
|
||||
- 或者封装了到该类型的引用的 `Pin`。
|
||||
|
||||
|
||||
我们将在 [第 18 章](../Ch17_Object_Oriented_Programming_Features_of_Rust.md) 中看到有关这一语法的更多内容。目前只需知道,当我们打算轮询某个未来值,来检查他处于 `Pending` 还是 `Ready(Output)` 状态时,就需要一个由 `Pin` 封装的指向该类型的可变引用。
|
||||
我们将在 [第 18 章](../Ch18_Object_Oriented_Programming_Features_of_Rust.md) 中看到有关这一语法的更多内容。目前只需知道,当我们打算轮询某个未来值,来检查他处于 `Pending` 还是 `Ready(Output)` 状态时,就需要一个由 `Pin` 封装的指向该类型的可变引用。
|
||||
|
||||
`Pin` 是针对 `&`、`&mut`、`Box` 和 `Rc` 等类指针类型的封装器。(从技术上讲,`Pin` 适用于实现 `Deref` 或 `DerefMut` 特质的类型,但这实际上相当于仅适用于引用和灵巧指针。)`Pin` 本身并非指针,也不具备 `Rc` 和 `Arc` 那样带有引用计数的自身行为;他纯粹是编译器用来强制执行指针使用约束的工具。
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ pub fn add_one(x: i32) -> i32 {
|
||||
|
||||
出于便利目的,运行 `cargo doc --open` 将针对咱们的当前代码箱的文档(以及所有咱们的代码箱的依赖项的文档)构建 HTML,并在 web 浏览器中打开结果。导航到 `add_one` 函数,咱们将看到文档注释中的文本是如何渲染的,如下图 14-01 中所示:
|
||||
|
||||
<a name="f_14-1">
|
||||
<a name="f_14-1"></a>
|
||||

|
||||
|
||||
**图 14-1**:`add_one` 函数的 HTML 文档
|
||||
|
||||
@@ -338,7 +338,7 @@ fn run(config: Config) -> Result<(), Box<dyn Error>>{
|
||||
|
||||
我们在这里做出了三处显著修改。首先,我们修改 `run` 函数的返回类型为 `Result<(), Box<dyn Error>>`。这个函数之前返回单元值类型,`()`,我们保留其为 `Ok` 情形下返回的值。
|
||||
|
||||
对于错误类型,我们使用了特质对象 `Box<dyn Error>` (并且我们以顶部的 `use` 语句带入了 `std::error::Error` 到作用域)。我们将在 [第 18 章](../Ch17_Object_Oriented_Programming_Features_of_Rust.md) 中介绍特质对象。目前,只需知道 `Box<(), Error>` 表示该函数将返回一个实现 `Error` 特质的类型,但我们不必指定返回值将是何特定类型。这赋予了我们在不同的错误情形下,返回可能为不同类型的错误值的灵活性。`dyn` 关键字是 *dynamic* 的缩写。
|
||||
对于错误类型,我们使用了特质对象 `Box<dyn Error>` (并且我们以顶部的 `use` 语句带入了 `std::error::Error` 到作用域)。我们将在 [第 18 章](../Ch18_Object_Oriented_Programming_Features_of_Rust.md) 中介绍特质对象。目前,只需知道 `Box<(), Error>` 表示该函数将返回一个实现 `Error` 特质的类型,但我们不必指定返回值将是何特定类型。这赋予了我们在不同的错误情形下,返回可能为不同类型的错误值的灵活性。`dyn` 关键字是 *dynamic* 的缩写。
|
||||
|
||||
其次,正如我们在 [第 9 章](../error_handling/result.md#-操作符快捷方式) 中讨论的那样,我们移除了对 `expect` 的调用,转而使用 `?` 运算符。与错误上的 `panic!` 不同,`?` 将返回当前函数中的错误值供调用者处理。
|
||||
|
||||
|
||||
16
src/main.rs
Normal file
16
src/main.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use std::process::Command;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
// Invoke mdbook build in the directory containing book.toml
|
||||
let status = Command::new("mdbook")
|
||||
.arg("build")
|
||||
.status()?;
|
||||
|
||||
if status.success() {
|
||||
println!("PDF successfully generated in book/pdf/output.pdf");
|
||||
} else {
|
||||
eprintln!("Failed to generate PDF");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -58,7 +58,7 @@ $ cargo run
|
||||
条件为假
|
||||
```
|
||||
|
||||
还值得注意的是,这段代码中的条件 *必须* 要个 `bool` 值。当条件不是个 `bool` 值时,我们将得到一个报错。例如,请尝试运行以下代码:
|
||||
还值得注意的是,这段代码中的条件 *必须* 是个 `bool` 值。当条件不是个 `bool` 值时,我们将得到一个报错。例如,请尝试运行以下代码:
|
||||
|
||||
|
||||
文件名:`src/main.rs`
|
||||
@@ -245,7 +245,7 @@ fn main() {
|
||||
```
|
||||
|
||||
|
||||
当我们运行这个程序时,我们将看到 `again!` 被不断打印,直到我们手动停止程序为止。大多数终端都支持 `crtl-C` 中断某个陷入连续循环程序。尝试一下:
|
||||
当我们运行这个程序时,我们将看到 `again!` 被不断打印,直到我们手动停止程序为止。大多数终端都支持 `ctrl-C` 中断某个陷入连续循环程序。尝试一下:
|
||||
|
||||
|
||||
```console
|
||||
@@ -280,7 +280,7 @@ again!
|
||||
> ```
|
||||
|
||||
|
||||
幸运的是,Rust 也提供了使用代码跳出循环的方法。咱们可放置 `break` 关键字在循环中,告诉程序何时停止执行循环。回想一下,我们在第 2 章 的 [猜对后退出](../Ch02_Programming_a_Guessing_Game.md#猜对后的退出) 小节的猜数游戏中的猜数游戏中就这样做了,当用户猜对数字赢得游戏时退出程序。
|
||||
幸运的是,Rust 也提供了使用代码跳出循环的方法。咱们可放置 `break` 关键字在循环中,告诉程序何时停止执行循环。回想一下,我们在第 2 章 的 [猜对后退出](../Ch02_Programming_a_Guessing_Game.md#猜对后的退出) 小节的猜数游戏中就这样做了,当用户猜对数字赢得游戏时退出程序。
|
||||
|
||||
在猜数游戏中我们还使用了 `continue`,其在循环中会告诉程序,跳过循环的本次迭代中任何剩余代码,而前往下一次迭代。
|
||||
|
||||
@@ -308,7 +308,7 @@ fn main() {
|
||||
|
||||
在其中的循环前,我们声明一个名为 `counter` 的变量并初始化其为 `0`。 然后,咱们声明一个名为 `result` 的变量保存从该循环返回的值。在该循环的每一次迭代时,我们都给 `counter` 变量加 `1`,然后检查 `counter` 是否等于 `10`。当等于 `10` 时,我们使用带有 `counter * 2` 值的 `break` 关键字。在这个循环之后,我们使用分号结束指派该值到 `result` 的语句。最后,我们打印 `result` 中的值,在本例中为 `20`。
|
||||
|
||||
我们还可在循环内 `return`。`break` 只会退出当前循环,而 `return` 则始终会推出当前函数。
|
||||
我们还可在循环内 `return`。`break` 只会退出当前循环,而 `return` 则始终会退出当前函数。
|
||||
|
||||
|
||||
> **译注**:这个示例还可写作如下。
|
||||
@@ -337,7 +337,7 @@ fn main() {
|
||||
### 以循环标签消除歧义
|
||||
|
||||
|
||||
当咱们有着循环内的循环(译注:嵌套循环)时,`break` 和 `continue` 就会应用于该处的最内层循环。咱们可选择在某个循环上指定一个 *循环标签,loop lable*,随后咱们可与 `break` 或 `continue` 一起使用,指定这两个关键字会应用到某个带标签的循环,而不是最内层循环。循环标签必须以单引号开头。下面是两个嵌套循环下的一个示例:
|
||||
当咱们有着循环内的循环(译注:嵌套循环)时,`break` 和 `continue` 就会应用于该处的最内层循环。咱们可选择在某个循环上指定一个 *循环标签,loop label*,随后咱们可与 `break` 或 `continue` 一起使用,指定这两个关键字会应用到某个带标签的循环,而不是最内层循环。循环标签必须以单引号开头。下面是两个嵌套循环下的一个示例:
|
||||
|
||||
|
||||
```rust
|
||||
@@ -367,7 +367,7 @@ fn main() {
|
||||
```
|
||||
|
||||
|
||||
其中外层循环有着标签 `'counting_up`,他将从 `0` 计数到 `2`。不带标签的内存循环会从 `10` 倒计数到 `9`。未指定标签的第一个 `break`,将只退出内层循环。那个 `break 'counting_up;` 语句将退出外层循环。这段代码会打印:
|
||||
其中外层循环有着标签 `'counting_up`,他将从 `0` 计数到 `2`。不带标签的内层循环会从 `10` 倒计数到 `9`。未指定标签的第一个 `break`,将只退出内层循环。那个 `break 'counting_up;` 语句将退出外层循环。这段代码会打印:
|
||||
|
||||
|
||||
```console
|
||||
@@ -480,7 +480,7 @@ fn main() {
|
||||
|
||||
当咱们运行这段代码时,我们将看到与清单 3-4 同样的输出。更重要的是,我们现在提高了代码的安全性,并消除了超出数组末尾,或因遍历不足远而遗漏某些项目等可能导致的 bug 的可能性。自 `for` 循环生成的机器码也会更加高效,因为索引不需要在每次迭代时都与数组长度比较。
|
||||
|
||||
使用 `for` 循环时,当咱们修改了数组中值的个数时,咱们将不需要向使用 [清单 3-4](#listing_3-4) 中用到的方法中那样,记住修改任何其他代码。
|
||||
使用 `for` 循环时,当咱们修改了数组中值的个数时,咱们将不需要像使用 [清单 3-4](#listing_3-4) 中用到的方法中那样,记住修改任何其他代码。
|
||||
|
||||
`for` 循环的安全性和简洁性,使其成为 Rust 中最常用到的循环结构。即使是在咱们打算运行某些代码一定次数的情形下,如清单 3-3 中使用 `while` 循环的倒计时示例中,大多数 Rustaceans 也会使用 `for` 循环。实现这点的方法,是使用由标准库提供的 `Range`,他会按顺序生成从一个数字开始到另一个数字前结束的所有数字。
|
||||
|
||||
@@ -507,7 +507,7 @@ fn main() {
|
||||
咱们做到了!这是蔚为壮观的一章:咱们学习了变量、标量与复合数据类型、函数、注释、`if` 表达式和循环!要练习这一章中讨论的概念,请尝试构建程序完成以下操作:
|
||||
|
||||
- 转换华氏和摄氏之间的温度;
|
||||
- 生成第 n 个斐波拉基数;
|
||||
- 生成第 n 个斐波那契数;
|
||||
- 利用圣诞颂歌 “The Twelve Days of Christmas” 中的重复,而打印出其歌词;
|
||||
|
||||
|
||||
@@ -518,7 +518,7 @@ fn main() {
|
||||
|
||||
|
||||
<details>
|
||||
<summary>“法式温度与摄氏温度的转换”</summary>
|
||||
<summary>“华氏温度与摄氏温度的转换”</summary>
|
||||
|
||||
```rust
|
||||
use std::io;
|
||||
@@ -533,11 +533,11 @@ fn cels_to_fah(c: f32) -> f32 {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println! ("法式温度与摄氏温度之间的转换");
|
||||
println! ("华氏温度与摄氏温度之间的转换");
|
||||
|
||||
loop {
|
||||
println! ("\n-----------------\n请选择:
|
||||
'1'-摄氏温度/'2'-法式温度/'Q'/\"quit\" 退出程序。
|
||||
'1'-摄氏温度/'2'-华氏温度/'Q'/\"quit\" 退出程序。
|
||||
'1'/'2'/'Q'/\"quit\"[1]:");
|
||||
|
||||
let mut temp_type = String::new();
|
||||
@@ -559,14 +559,14 @@ fn main() {
|
||||
println! ("请输入要转换的摄氏温度:");
|
||||
let temp = get_temp_input();
|
||||
|
||||
println! ("摄氏温度: {:.2}°C,约为法氏温度:{:.2}°F", temp, cels_to_fah(temp));
|
||||
println! ("摄氏温度: {:.2}°C,约为华氏温度:{:.2}°F", temp, cels_to_fah(temp));
|
||||
}
|
||||
|
||||
if temp_type.eq("2") {
|
||||
println! ("请输入要转换的法氏温度:");
|
||||
println! ("请输入要转换的华氏温度:");
|
||||
let temp = get_temp_input();
|
||||
|
||||
println! ("法氏温度:{:.2}°F,约为摄氏温度:{:.2}°C", temp, fah_to_cels(temp));
|
||||
println! ("华氏温度:{:.2}°F,约为摄氏温度:{:.2}°C", temp, fah_to_cels(temp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -594,7 +594,7 @@ fn get_temp_input() -> f32 {
|
||||
|
||||
|
||||
<details>
|
||||
<summary>"生成第 n 个斐波拉基数"</summary>
|
||||
<summary>"生成第 n 个斐波那契数"</summary>
|
||||
|
||||
|
||||
```rust
|
||||
@@ -612,7 +612,7 @@ fn nth_fibonacci(n: u64) -> u64 {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println! ("找出第 n 个斐波拉基数");
|
||||
println! ("找出第 n 个斐波那契数");
|
||||
|
||||
'main_loop: loop {
|
||||
println! ("请输入 n: (Q/quit 退出程序)");
|
||||
@@ -640,7 +640,7 @@ fn main() {
|
||||
};
|
||||
};
|
||||
|
||||
println! ("第 {} 个斐波拉基数为:{}",
|
||||
println! ("第 {} 个斐波那契数为:{}",
|
||||
n,
|
||||
nth_fibonacci(n).to_formatted_string(&Locale::en));
|
||||
}
|
||||
@@ -664,7 +664,7 @@ fn main() {
|
||||
"sixth",
|
||||
"seventh",
|
||||
"eighth",
|
||||
"nineth",
|
||||
"ninth",
|
||||
"tenth",
|
||||
"eleventh",
|
||||
"twelfth"
|
||||
|
||||
@@ -163,14 +163,7 @@ impl Rectangle {
|
||||
当我们以清单 5-14 中的 `main` 函数运行这段代码时,我们将得到我们想要的输出。方法可以取我们于 `self` 参数后添加到签名的多个参数,而这些参数会与函数中的参数一样生效。
|
||||
|
||||
|
||||
> **译注**:实际上,这个 `can_hold` 的实现有错误,因为其没有考虑到矩形倒转后可以容纳的情况,改进后的 `can_hold` 如下。
|
||||
>
|
||||
> ```rust
|
||||
> fn can_hold(&self, other: &Rectangle) -> bool {
|
||||
> (self.width > other.width && self.height > other.height)
|
||||
> || (self.width > other.height && self.height > other.width)
|
||||
> }
|
||||
> ```
|
||||
> **译注**:实际上,英文原版的 can_hold 实现未考虑矩形旋转后仍可容纳的情况,此处已修正。
|
||||
|
||||
|
||||
## 关联函数
|
||||
|
||||
@@ -342,7 +342,14 @@
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<p>若这里内容有帮助到你,请选择上述方式向 xfoss.com 捐赠。</p>
|
||||
<p>若这里内容有帮助到你,请选择上述方式向 xfoss.com 捐赠。或通过 PayPal:</p>
|
||||
<form style="text-align: center" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="JU6TNGPCAAVQA" />
|
||||
<input type="hidden" name="currency_code" value="USD" />
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif" border="0" name="submit" title="有了PayPal,您可以更安全便捷地在线付款!" alt="立即购买" />
|
||||
</form>
|
||||
|
||||
<button class="close-button">Close</button>
|
||||
</dialog>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user