Merge pull request #413 from AllanDowney/patch-2

Update: unified format
pull/414/head
孙飞Sunface 3 years ago committed by GitHub
commit dfee1f125c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,7 +1,7 @@
# Rust高级进阶 # Rust 高级进阶
恭喜你学会Rust基础后金丹大道已在向你招手大部分 Rust 代码对你来说都是家常便饭,简单得很。可是,对于一门难度传言在外的语言,怎么可能如此简单的就被征服,最难的生命周期,咱还没见过长啥样呢。 恭喜你,学会 Rust 基础后,金丹大道已在向你招手,大部分 Rust 代码对你来说都是家常便饭,简单得很。可是,对于一门难度传言在外的语言,怎么可能如此简单的就被征服,最难的生命周期,咱还没见过长啥样呢。
从本章开始我们将进入Rust的进阶学习环节与基础环节不同的是由于你已经对 Rust 有了一定的认识,因此我们**不会再对很多细节进行翻来覆去的详细讲解,甚至会一带而过**。 从本章开始,我们将进入 Rust 的进阶学习环节,与基础环节不同的是,由于你已经对 Rust 有了一定的认识,因此我们**不会再对很多细节进行翻来覆去的详细讲解,甚至会一带而过**。
总之,欢迎来到高级 Rust 的世界,全新的 Boss全新的装备你准备好了吗 总之,欢迎来到高级 Rust 的世界,全新的 Boss全新的装备你准备好了吗

@ -5,7 +5,7 @@
- 就像编译器大部分时候可以自动推导类型 <-> 一样,编译器大多数时候也可以自动推导生命周期 - 就像编译器大部分时候可以自动推导类型 <-> 一样,编译器大多数时候也可以自动推导生命周期
- 在多种类型存在时,编译器往往要求我们手动标明类型 <-> 当多个生命周期存在,且编译器无法推导出某个引用的生命周期时,就需要我们手动标明生命周期 - 在多种类型存在时,编译器往往要求我们手动标明类型 <-> 当多个生命周期存在,且编译器无法推导出某个引用的生命周期时,就需要我们手动标明生命周期
Rust 生命周期之所以难,是因为这个概念对于我们来说是全新的,没有其它编程语言的经验可以借鉴。当你觉得难的时候,不用过于担心,这个难对于所有人都是平等的,多点付出就能早点解决此拦路虎,同时本书也会尽力帮助大家减少学习难度(生命周期很可能是Rust中最难的部分)。 Rust 生命周期之所以难,是因为这个概念对于我们来说是全新的,没有其它编程语言的经验可以借鉴。当你觉得难的时候,不用过于担心,这个难对于所有人都是平等的,多点付出就能早点解决此拦路虎,同时本书也会尽力帮助大家减少学习难度(生命周期很可能是 Rust 中最难的部分)。
## 悬垂指针和生命周期 ## 悬垂指针和生命周期
生命周期的主要作用是避免悬垂引用,它会导致程序引用了本不该引用的数据: 生命周期的主要作用是避免悬垂引用,它会导致程序引用了本不该引用的数据:
@ -29,16 +29,16 @@ Rust 生命周期之所以难,是因为这个概念对于我们来说是全新
此处 `r` 就是一个悬垂指针,它引用了提前被释放的变量 `x`,可以预料到,这段代码会报错: 此处 `r` 就是一个悬垂指针,它引用了提前被释放的变量 `x`,可以预料到,这段代码会报错:
```console ```console
error[E0597]: `x` does not live long enough // x活得不够久 error[E0597]: `x` does not live long enough // `x` 活得不够久
--> src/main.rs:7:17 --> src/main.rs:7:17
| |
7 | r = &x; 7 | r = &x;
| ^^ borrowed value does not live long enough // 被借用的x活得不够久 | ^^ borrowed value does not live long enough // 被借用的 `x` 活得不够久
8 | } 8 | }
| - `x` dropped here while still borrowed // x在这里被丢弃但是它依然还在被借用 | - `x` dropped here while still borrowed // `x` 在这里被丢弃,但是它依然还在被借用
9 | 9 |
10 | println!("r: {}", r); 10 | println!("r: {}", r);
| - borrow later used here // 对x的借用在此处被使用 | - borrow later used here // 对 `x` 的借用在此处被使用
``` ```
在这里 `r` 拥有更大的作用域,或者说**活得更久**。如果 Rust 不阻止该垂悬引用的发生,那么当 `x` 被释放后,`r` 所引用的值就不再是合法的,会导致我们程序发生异常行为,且该异常行为有时候会很难被发现。 在这里 `r` 拥有更大的作用域,或者说**活得更久**。如果 Rust 不阻止该垂悬引用的发生,那么当 `x` 被释放后,`r` 所引用的值就不再是合法的,会导致我们程序发生异常行为,且该异常行为有时候会很难被发现。
@ -55,7 +55,7 @@ error[E0597]: `x` does not live long enough // x活得不够久
} // -+ | } // -+ |
// | // |
println!("r: {}", r); // | println!("r: {}", r); // |
} } // ---------+
``` ```
这段代码和之前的一模一样,唯一的区别在于增加了对变量生命周期的注释。这里,`r` 变量被赋予了生命周期 `'a``x` 被赋予了生命周期 `'b`,从图示上可以明显看出生命周期 `'b``'a` 小很多。 这段代码和之前的一模一样,唯一的区别在于增加了对变量生命周期的注释。这里,`r` 变量被赋予了生命周期 `'a``x` 被赋予了生命周期 `'b`,从图示上可以明显看出生命周期 `'b``'a` 小很多。
@ -126,7 +126,7 @@ help: consider introducing a named lifetime parameter // 考虑引入一个生
因此,这时就回到了文章开头说的内容:在存在多个引用时,编译器有时会无法自动推导生命周期,此时就需要我们手动去标注,通过为参数标注合适的生命周期来帮助编译器进行借用检查的分析。 因此,这时就回到了文章开头说的内容:在存在多个引用时,编译器有时会无法自动推导生命周期,此时就需要我们手动去标注,通过为参数标注合适的生命周期来帮助编译器进行借用检查的分析。
## 生命周期标注语法 ## 生命周期标注语法
> 生命周期标注并不会改变任何引用的实际作用域 - 鲁迅 > 生命周期标注并不会改变任何引用的实际作用域 -- 鲁迅
鲁迅说过的话,总是值得重点标注,当你未来更加理解生命周期时,你才会发现这句话的精髓和重要!现在先简单记住,**标记的生命周期只是为了取悦编译器,让编译器不要难为我们**,记住了吗?没记住,再回头看一遍,这对未来你遇到生命周期问题时会有很大的帮助! 鲁迅说过的话,总是值得重点标注,当你未来更加理解生命周期时,你才会发现这句话的精髓和重要!现在先简单记住,**标记的生命周期只是为了取悦编译器,让编译器不要难为我们**,记住了吗?没记住,再回头看一遍,这对未来你遇到生命周期问题时会有很大的帮助!
@ -533,13 +533,13 @@ Bang一个复杂的玩意儿被甩到了你面前就问怕不怕
就关键点稍微解释下: 就关键点稍微解释下:
- `'a: 'b`,是生命周期约束语法,跟泛型约束非常相似,用于说明`'a`必须比`'b`活得久 - `'a: 'b`,是生命周期约束语法,跟泛型约束非常相似,用于说明 `'a` 必须比 `'b` 活得久
- 为了实现这一点,必须把`'a`和`'b`都在同一个地方声明,你不能把`'a`在`impl`后面声明,而把`'b`在方法中声明 - 为了实现这一点,必须把 `'a` `'b` 都在同一个地方声明,你不能把 `'a` `impl` 后面声明,而把 `'b` 在方法中声明
总之,实现方法比想象中简单:加一个约束,就能暗示编译器,尽管引用吧,反正我想引用的内容比我活得久,爱咋咋地,我怎么都不会引用到无效的内容! 总之,实现方法比想象中简单:加一个约束,就能暗示编译器,尽管引用吧,反正我想引用的内容比我活得久,爱咋咋地,我怎么都不会引用到无效的内容!
## 静态生命周期 ## 静态生命周期
在Rust中有一个非常特殊的生命周期那就是 `'static`,拥有该生命周期的引用可以和整个程序活得一样久。 Rust 中有一个非常特殊的生命周期,那就是 `'static`,拥有该生命周期的引用可以和整个程序活得一样久。
在之前我们学过字符串字面量,提到过它是被硬编码进 Rust 的二进制文件中,因此这些字符串变量全部具有 `'static` 的生命周期: 在之前我们学过字符串字面量,提到过它是被硬编码进 Rust 的二进制文件中,因此这些字符串变量全部具有 `'static` 的生命周期:
```rust ```rust
@ -586,8 +586,8 @@ where
依然是熟悉的配方 `longest`,但是多了一段废话: `ann`,因为要用格式化 `{}` 来输出 `ann`,因此需要它实现 `Display` 特征。 依然是熟悉的配方 `longest`,但是多了一段废话: `ann`,因为要用格式化 `{}` 来输出 `ann`,因此需要它实现 `Display` 特征。
## 总结 ## 总结
我不知道支撑我一口气写完的勇气是什么也许是不做完不爽夫斯基也许是一些读者对本书的期待不管如何这章足足写了17000字可惜不是写小说不然肯定可以获取很多月票 :) 我不知道支撑我一口气写完的勇气是什么,也许是不做完不爽夫斯基,也许是一些读者对本书的期待,不管如何,这章足足写了 17000 字,可惜不是写小说,不然肯定可以获取很多月票 :)
从本章开始,最大的收获就是可以在结构体中使用引用类型了,说实话,为了引入这个特性,我已经憋了足足30章节。。 从本章开始,最大的收获就是可以在结构体中使用引用类型了,说实话,为了引入这个特性,我已经憋了足足 30 章节……
但是,还没完,是的,就算是将近2万字,生命周期的旅程依然没有完结,下一节将介绍一些关于生命周期的高级特性,这些特性你在其它中文书中目前还看不到的。 但是,还没完,是的,就算是将近万字,生命周期的旅程依然没有完结,下一节将介绍一些关于生命周期的高级特性,这些特性你在其它中文书中目前还看不到的。

@ -2,7 +2,7 @@
但凡经历过 C/C++ 或 Go 语言 1.10 版本之前的用户都知道,一个好的包管理工具有多么的重要!!我那个时候是如此的渴望类似 `nodejs``npm `包管理工具,但是却求而不得。 但凡经历过 C/C++ 或 Go 语言 1.10 版本之前的用户都知道,一个好的包管理工具有多么的重要!!我那个时候是如此的渴望类似 `nodejs``npm `包管理工具,但是却求而不得。
包管理工具最重要的意义就是**任何用户拿到你的代码,都能运行起来**",而不会因为各种包版本依赖焦头烂额。 包管理工具最重要的意义就是**任何用户拿到你的代码,都能运行起来**,而不会因为各种包版本依赖焦头烂额。
Go 语言在 1.10 版本之前,所有的包都是在 `github.com` 下存放,导致了所有的项目都公用一套依赖代码,在本地项目复杂后,这简直是一种灾难。 Go 语言在 1.10 版本之前,所有的包都是在 `github.com` 下存放,导致了所有的项目都公用一套依赖代码,在本地项目复杂后,这简直是一种灾难。

@ -14,7 +14,7 @@
打开终端并输入下面命令: 打开终端并输入下面命令:
```console ```console
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh $ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
``` ```
这个命令将下载一个脚本并开始安装 `rustup` 工具,此工具将安装 Rust 的最新稳定版本。可能会提示你输入管理员密码。 这个命令将下载一个脚本并开始安装 `rustup` 工具,此工具将安装 Rust 的最新稳定版本。可能会提示你输入管理员密码。
@ -34,7 +34,7 @@ Rust 对运行环境的依赖和 Go 语言很像,几乎所有环境都可以
**MacOS 下:** **MacOS 下:**
```console ```console
xcode-select --install $ xcode-select --install
``` ```
**Linux 下:** **Linux 下:**
@ -82,7 +82,7 @@ Current installation options:
配置好后,在 MSYS 中输入下面的命令来安装 rustup。 配置好后,在 MSYS 中输入下面的命令来安装 rustup。
```bash ```bash
curl https://sh.rustup.rs -sSf | sh $ curl https://sh.rustup.rs -sSf | sh
``` ```
之后,根据以下输出进行配置。 之后,根据以下输出进行配置。
@ -135,7 +135,7 @@ Current installation options:
要卸载 Rust 和 `rustup`,在终端执行以下命令即可卸载: 要卸载 Rust 和 `rustup`,在终端执行以下命令即可卸载:
```bash ```bash
rustup self uninstall $ rustup self uninstall
``` ```
## 检查安装是否成功 ## 检查安装是否成功
@ -143,10 +143,10 @@ rustup self uninstall
检查是否正确安装了 Rust可打开终端并输入下面这行此时能看到最新发布的稳定版本的版本号、提交哈希值和提交日期 检查是否正确安装了 Rust可打开终端并输入下面这行此时能看到最新发布的稳定版本的版本号、提交哈希值和提交日期
```bash ```bash
rustc -V $ rustc -V
rustc 1.56.1 (59eed8a2a 2021-11-01) rustc 1.56.1 (59eed8a2a 2021-11-01)
cargo -V $ cargo -V
cargo 1.57.0 (b2e52d7ca 2021-10-21) cargo 1.57.0 (b2e52d7ca 2021-10-21)
``` ```
> 注:若发现版本号不同,以您的版本号为准 > 注:若发现版本号不同,以您的版本号为准

Loading…
Cancel
Save