Update(appendix): unified format 9

pull/509/head
Allan Downey 3 years ago
parent 2fb33f47da
commit 9c0908ac8c

@ -4,11 +4,11 @@
在本附录中,我们列举了所有标准库存在的 `derive` 特征,每个特征覆盖了以下内容 在本附录中,我们列举了所有标准库存在的 `derive` 特征,每个特征覆盖了以下内容
* 该特征将会派生什么样的操作符和方法 - 该特征将会派生什么样的操作符和方法
*`derive` 提供什么样的特征实现 -`derive` 提供什么样的特征实现
* 实现特征对于类型意味着什么 - 实现特征对于类型意味着什么
* 你需要什么条件来实现该特征 - 你需要什么条件来实现该特征
* 特征示例 - 特征示例
如果你希望不同于 `derive` 属性所提供的行为,请查阅 [标准库文档](https://doc.rust-lang.org/std/index.html) 中每个特征的细节以了解如何手动实现它们。 如果你希望不同于 `derive` 属性所提供的行为,请查阅 [标准库文档](https://doc.rust-lang.org/std/index.html) 中每个特征的细节以了解如何手动实现它们。

@ -3,12 +3,14 @@
在[语句与表达式](https://course.rs/basic/base-type/statement-expression.html)章节中,我们对表达式有过介绍,下面对这些常用表达式进行一一说明。 在[语句与表达式](https://course.rs/basic/base-type/statement-expression.html)章节中,我们对表达式有过介绍,下面对这些常用表达式进行一一说明。
### 基本表达式 ### 基本表达式
```rust ```rust
let n = 3; let n = 3;
let s = "test"; let s = "test";
``` ```
### if 表达式 ### if 表达式
```rust ```rust
fn main() { fn main() {
let var1 = 10; let var1 = 10;
@ -26,6 +28,7 @@ fn main() {
通过 `if` 表达式将值赋予 `var2` 通过 `if` 表达式将值赋予 `var2`
你还可以在循环中结合 `continue` 、`break` 来使用: 你还可以在循环中结合 `continue` 、`break` 来使用:
```rust ```rust
let mut v = 0; let mut v = 0;
for i in 1..10 { for i in 1..10 {
@ -39,6 +42,7 @@ println!("{}", v);
``` ```
### if let 表达式 ### if let 表达式
```rust ```rust
let o = Some(3); let o = Some(3);
let v = if let Some(x) = o { let v = if let Some(x) = o {
@ -49,6 +53,7 @@ let v = if let Some(x) = o {
``` ```
### match 表达式 ### match 表达式
```rust ```rust
let o = Some(3); let o = Some(3);
let v = match o { let v = match o {
@ -58,6 +63,7 @@ let v = match o {
``` ```
### loop 表达式 ### loop 表达式
```rust ```rust
let mut n = 0; let mut n = 0;
let v = loop { let v = loop {
@ -69,6 +75,7 @@ let v = loop {
``` ```
### 语句块 {} ### 语句块 {}
```rust ```rust
let mut n = 0; let mut n = 0;
let v = { let v = {

@ -2,67 +2,66 @@
下面的列表包含 Rust 中正在使用或者以后会用到的关键字。因此,这些关键字不能被用作标识符(除了[原生标识符](#原生标识符)),包括函数、变量、参数、结构体字段、模块、包、常量、宏、静态值、属性、类型、特征或生命周期。 下面的列表包含 Rust 中正在使用或者以后会用到的关键字。因此,这些关键字不能被用作标识符(除了[原生标识符](#原生标识符)),包括函数、变量、参数、结构体字段、模块、包、常量、宏、静态值、属性、类型、特征或生命周期。
### 目前正在使用的关键字 ### 目前正在使用的关键字
如下关键字目前有对应其描述的功能。 如下关键字目前有对应其描述的功能。
* `as` - 强制类型转换,或`use` 和 `extern crate`包和模块引入语句中的重命名 - `as` - 强制类型转换,或`use` 和 `extern crate`包和模块引入语句中的重命名
* `break` - 立刻退出循环 - `break` - 立刻退出循环
* `const` - 定义常量或原生常量指针constant raw pointer - `const` - 定义常量或原生常量指针constant raw pointer
* `continue` - 继续进入下一次循环迭代 - `continue` - 继续进入下一次循环迭代
* `crate` - 链接外部包 - `crate` - 链接外部包
* `dyn` - 动态分发特征对象 - `dyn` - 动态分发特征对象
* `else` - 作为 `if``if let` 控制流结构的 fallback - `else` - 作为 `if``if let` 控制流结构的 fallback
* `enum` - 定义一个枚举类型 - `enum` - 定义一个枚举类型
* `extern` - 链接一个外部包,或者一个宏变量(该变量定义在另外一个包中) - `extern` - 链接一个外部包,或者一个宏变量(该变量定义在另外一个包中)
* `false` - 布尔值 `false` - `false` - 布尔值 `false`
* `fn` - 定义一个函数或 **函数指针类型** (*function pointer type*) - `fn` - 定义一个函数或 **函数指针类型** (_function pointer type_)
* `for` - 遍历一个迭代器或实现一个 trait 或者指定一个更高级的生命周期 - `for` - 遍历一个迭代器或实现一个 trait 或者指定一个更高级的生命周期
* `if` - 基于条件表达式的结果来执行相应的分支 - `if` - 基于条件表达式的结果来执行相应的分支
* `impl` - 为结构体或者特征实现具体功能 - `impl` - 为结构体或者特征实现具体功能
* `in` - `for` 循环语法的一部分 - `in` - `for` 循环语法的一部分
* `let` - 绑定一个变量 - `let` - 绑定一个变量
* `loop` - 无条件循环 - `loop` - 无条件循环
* `match` - 模式匹配 - `match` - 模式匹配
* `mod` - 定义一个模块 - `mod` - 定义一个模块
* `move` - 使闭包获取其所捕获项的所有权 - `move` - 使闭包获取其所捕获项的所有权
* `mut` - 在引用、原生指针或模式绑定中使用,表明变量是可变的 - `mut` - 在引用、原生指针或模式绑定中使用,表明变量是可变的
* `pub` - 表示结构体字段、`impl` 块或模块的公共可见性 - `pub` - 表示结构体字段、`impl` 块或模块的公共可见性
* `ref` - 通过引用绑定 - `ref` - 通过引用绑定
* `return` - 从函数中返回 - `return` - 从函数中返回
* `Self` - 实现特征类型的类型别名 - `Self` - 实现特征类型的类型别名
* `self` - 表示方法本身或当前模块 - `self` - 表示方法本身或当前模块
* `static` - 表示全局变量或在整个程序执行期间保持其生命周期 - `static` - 表示全局变量或在整个程序执行期间保持其生命周期
* `struct` - 定义一个结构体 - `struct` - 定义一个结构体
* `super` - 表示当前模块的父模块 - `super` - 表示当前模块的父模块
* `trait` - 定义一个特征 - `trait` - 定义一个特征
* `true` - 布尔值 `true` - `true` - 布尔值 `true`
* `type` - 定义一个类型别名或关联类型 - `type` - 定义一个类型别名或关联类型
* `unsafe` - 表示不安全的代码、函数、特征或实现 - `unsafe` - 表示不安全的代码、函数、特征或实现
* `use` - 在当前代码范围内(模块或者花括号对)引入外部的包、模块等 - `use` - 在当前代码范围内(模块或者花括号对)引入外部的包、模块等
* `where` - 表示一个约束类型的从句 - `where` - 表示一个约束类型的从句
* `while` - 基于一个表达式的结果判断是否继续循环 - `while` - 基于一个表达式的结果判断是否继续循环
### 保留做将来使用的关键字 ### 保留做将来使用的关键字
如下关键字没有任何功能,不过由 Rust 保留以备将来的应用。 如下关键字没有任何功能,不过由 Rust 保留以备将来的应用。
* `abstract` - `abstract`
* `async` - `async`
* `await` - `await`
* `become` - `become`
* `box` - `box`
* `do` - `do`
* `final` - `final`
* `macro` - `macro`
* `override` - `override`
* `priv` - `priv`
* `try` - `try`
* `typeof` - `typeof`
* `unsized` - `unsized`
* `virtual` - `virtual`
* `yield` - `yield`
### 原生标识符 ### 原生标识符

@ -1,6 +1,5 @@
## 附录 B运算符与符号 ## 附录 B运算符与符号
该附录包含了 Rust 目前出现过的各种符号,这些符号之前都分散在各个章节中。 该附录包含了 Rust 目前出现过的各种符号,这些符号之前都分散在各个章节中。
### 运算符 ### 运算符
@ -12,7 +11,7 @@
<span class="caption">表 B-1运算符</span> <span class="caption">表 B-1运算符</span>
| 运算符 | 示例 | 解释 | 是否可重载 | | 运算符 | 示例 | 解释 | 是否可重载 |
|----------|---------|-------------|---------------| | ------------------------- | ------------------------------------------------------- | ---------------------------------- | -------------- |
| `!` | `ident!(...)`, `ident!{...}`, `ident![...]` | 宏展开 | | | `!` | `ident!(...)`, `ident!{...}`, `ident![...]` | 宏展开 | |
| `!` | `!expr` | 按位非或逻辑非 | `Not` | | `!` | `!expr` | 按位非或逻辑非 | `Not` |
| `!=` | `var != expr` | 不等比较 | `PartialEq` | | `!=` | `var != expr` | 不等比较 | `PartialEq` |
@ -68,13 +67,12 @@
| <code>&vert;&vert;</code> | <code>expr &vert;&vert; expr</code> | 逻辑或 | | | <code>&vert;&vert;</code> | <code>expr &vert;&vert; expr</code> | 逻辑或 | |
| `?` | `expr?` | 错误传播 | | | `?` | `expr?` | 错误传播 | |
### 非运算符符号 ### 非运算符符号
<span class="caption">表 B-2独立语法</span> <span class="caption">表 B-2独立语法</span>
| 符号 | 解释 | | 符号 | 解释 |
|--------|-------------| | ------------------------------------------- | ------------------------------------------------------ |
| `'ident` | 生命周期名称或循环标签 | | `'ident` | 生命周期名称或循环标签 |
| `...u8`, `...i32`, `...f64`, `...usize`, 等 | 指定类型的数值常量 | | `...u8`, `...i32`, `...f64`, `...usize`, 等 | 指定类型的数值常量 |
| `"..."` | 字符串常量 | | `"..."` | 字符串常量 |
@ -92,7 +90,7 @@
<span class="caption">表 B-3路径相关语法</span> <span class="caption">表 B-3路径相关语法</span>
| 符号 | 解释 | | 符号 | 解释 |
|--------|-------------| | --------------------------------------- | ----------------------------------------------------------------- |
| `ident::ident` | 命名空间路径 | | `ident::ident` | 命名空间路径 |
| `::path` | 从当前的包的根路径开始的相对路径 | | `::path` | 从当前的包的根路径开始的相对路径 |
| `self::path` | 与当前模块相对的路径(如一个显式相对路径) | | `self::path` | 与当前模块相对的路径(如一个显式相对路径) |
@ -103,13 +101,12 @@
| `type::method(...)` | 使用类型名进行方法调用, 以消除方法调用的二义性 | | `type::method(...)` | 使用类型名进行方法调用, 以消除方法调用的二义性 |
| `<type as trait>::method(...)` | 将类型转换为特征,再进行方法调用,以消除方法调用的二义性 | | `<type as trait>::method(...)` | 将类型转换为特征,再进行方法调用,以消除方法调用的二义性 |
表 B-4 展示了使用泛型参数时用到的符号。 表 B-4 展示了使用泛型参数时用到的符号。
<span class="caption">表 B-4泛型</span> <span class="caption">表 B-4泛型</span>
| 符号 | 解释 | | 符号 | 解释 |
|--------|-------------| | ------------------------------ | ------------------------------------------------------------------------------------------------- |
| `path<...>` | 为一个类型中的泛型指定具体参数(如 `Vec<u8>` | | `path<...>` | 为一个类型中的泛型指定具体参数(如 `Vec<u8>` |
| `path::<...>`, `method::<...>` | 为一个泛型、函数或表达式中的方法指定具体参数,通常指双冒号(turbofish)(如 `"42".parse::<i32>()` | | `path::<...>`, `method::<...>` | 为一个泛型、函数或表达式中的方法指定具体参数,通常指双冒号(turbofish)(如 `"42".parse::<i32>()` |
| `fn ident<...> ...` | 泛型函数定义 | | `fn ident<...> ...` | 泛型函数定义 |
@ -124,7 +121,7 @@
<span class="caption">表 B-5特征约束</span> <span class="caption">表 B-5特征约束</span>
| 符号 | 解释 | | 符号 | 解释 |
|--------|-------------| | ----------------------------- | ---------------------------------------------------------------------------------------- |
| `T: U` | 泛型参数 `T`需实现`U`类型 | | `T: U` | 泛型参数 `T`需实现`U`类型 |
| `T: 'a` | 泛型 `T` 的生命周期必须长于 `'a`(意味着该类型不能传递包含生命周期短于 `'a` 的任何引用) | | `T: 'a` | 泛型 `T` 的生命周期必须长于 `'a`(意味着该类型不能传递包含生命周期短于 `'a` 的任何引用) |
| `T : 'static` | 泛型 T 只能使用声明周期为'static 的引用 | | `T : 'static` | 泛型 T 只能使用声明周期为'static 的引用 |
@ -137,7 +134,7 @@
<span class="caption">表 B-6宏与属性</span> <span class="caption">表 B-6宏与属性</span>
| 符号 | 解释 | | 符号 | 解释 |
|--------|-------------| | ------------------------------------------- | -------- |
| `#[meta]` | 外部属性 | | `#[meta]` | 外部属性 |
| `#![meta]` | 内部属性 | | `#![meta]` | 内部属性 |
| `$ident` | 宏替换 | | `$ident` | 宏替换 |
@ -150,7 +147,7 @@
<span class="caption">表 B-7注释</span> <span class="caption">表 B-7注释</span>
| 符号 | 注释 | | 符号 | 注释 |
|--------|-------------| | ---------- | -------------------- |
| `//` | 行注释 | | `//` | 行注释 |
| `//!` | 内部行(hang)文档注释 | | `//!` | 内部行(hang)文档注释 |
| `///` | 外部行文档注释 | | `///` | 外部行文档注释 |
@ -163,7 +160,7 @@
<span class="caption">表 B-8元组</span> <span class="caption">表 B-8元组</span>
| 符号 | 解释 | | 符号 | 解释 |
|--------|-------------| | ------------------------ | ------------------------------------------------------------------------ |
| `()` | 空元组(亦称单元),即是字面值也是类型 | | `()` | 空元组(亦称单元),即是字面值也是类型 |
| `(expr)` | 括号表达式 | | `(expr)` | 括号表达式 |
| `(expr,)` | 单一元素元组表达式 | | `(expr,)` | 单一元素元组表达式 |
@ -178,7 +175,7 @@
<span class="caption">表 B-9大括号</span> <span class="caption">表 B-9大括号</span>
| 符号 | 解释 | | 符号 | 解释 |
|---------|-------------| | ------------ | ------------ |
| `{...}` | 代码块表达式 | | `{...}` | 代码块表达式 |
| `Type {...}` | 结构体字面值 | | `Type {...}` | 结构体字面值 |
@ -187,7 +184,7 @@
<span class="caption">表 B-10方括号</span> <span class="caption">表 B-10方括号</span>
| 符号 | 解释 | | 符号 | 解释 |
|---------|-------------| | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `[...]` | 数组 | | `[...]` | 数组 |
| `[expr; len]` | 数组里包含`len`个`expr` | | `[expr; len]` | 数组里包含`len`个`expr` |
| `[type; len]` | 数组里包含了`len`个`type`类型的对象 | | `[type; len]` | 数组里包含了`len`个`type`类型的对象 |

@ -1,7 +1,8 @@
# 附录 FRust 版本发布 # 附录 FRust 版本发布
## Rust 版本说明 ## Rust 版本说明
早在第一章,我们见过 `cargo new`*Cargo.toml* 中增加了一些有关 `edition` 的元数据。本附录将解释其意义!
早在第一章,我们见过 `cargo new`_Cargo.toml_ 中增加了一些有关 `edition` 的元数据。本附录将解释其意义!
与其它语言相比Rust 的更新迭代较为频繁(得益于精心设计过的发布流程以及 Rust 语言开发者团队管理): 与其它语言相比Rust 的更新迭代较为频繁(得益于精心设计过的发布流程以及 Rust 语言开发者团队管理):
@ -14,10 +15,9 @@
- 对于一般的用户edition 的发布会告诉这些用户Rust 语言相比上次大版本发布,有了重大的改进,值得一看 - 对于一般的用户edition 的发布会告诉这些用户Rust 语言相比上次大版本发布,有了重大的改进,值得一看
- 对于 Rust 语言开发者,可以让他们的工作成果更快的被世人所知,不必锦衣夜行 - 对于 Rust 语言开发者,可以让他们的工作成果更快的被世人所知,不必锦衣夜行
在本文档编写时Rust 已经有三个版本Rust 2015、2018、2021。本书基于 `Rust 2021 edition` 编写。 在本文档编写时Rust 已经有三个版本Rust 2015、2018、2021。本书基于 `Rust 2021 edition` 编写。
*Cargo.toml* 中的 `edition` 字段表明代码应该使用哪个版本编译。如果该字段不存在,其默认为 `2021` 以提供后向兼容性。 _Cargo.toml_ 中的 `edition` 字段表明代码应该使用哪个版本编译。如果该字段不存在,其默认为 `2021` 以提供后向兼容性。
每个项目都可以选择不同于默认的 `Rust 2021 edition` 的版本。这样,版本可能会包含不兼容的修改,比如新版本中新增的关键字可能会与老代码中的标识符冲突并导致错误。不过,除非你选择应用这些修改,否则旧代码依然能够被编译,即便你升级了编译器版本。 每个项目都可以选择不同于默认的 `Rust 2021 edition` 的版本。这样,版本可能会包含不兼容的修改,比如新版本中新增的关键字可能会与老代码中的标识符冲突并导致错误。不过,除非你选择应用这些修改,否则旧代码依然能够被编译,即便你升级了编译器版本。
@ -27,7 +27,6 @@
请查看 [Edition Guide](https://rust-lang-nursery.github.io/edition-guide/) 了解更多细节,这是一个完全介绍版本的书籍,包括如何通过 `cargo fix` 自动将代码迁移到新版本。 请查看 [Edition Guide](https://rust-lang-nursery.github.io/edition-guide/) 了解更多细节,这是一个完全介绍版本的书籍,包括如何通过 `cargo fix` 自动将代码迁移到新版本。
## Rust 自身开发流程 ## Rust 自身开发流程
本附录介绍 Rust 语言自身是如何开发的以及这如何影响作为 Rust 开发者的你。 本附录介绍 Rust 语言自身是如何开发的以及这如何影响作为 Rust 开发者的你。
@ -40,11 +39,11 @@
### Choo, Choo! ~~ 小火车发布流程启动 ### Choo, Choo! ~~ 小火车发布流程启动
开发 Rust 语言是基于一个**火车时刻表**来进行的:所有的开发工作在 Master 分支上完成但是发布就像火车时刻表一样拥有不同的时间发布采用的软件发布列车模型被用于思科IOS和等其它软件项目。Rust 有三个 **发布通道***release channel* 开发 Rust 语言是基于一个**火车时刻表**来进行的:所有的开发工作在 Master 分支上完成,但是发布就像火车时刻表一样,拥有不同的时间,发布采用的软件发布列车模型,被用于思科 IOS 和等其它软件项目。Rust 有三个 **发布通道**_release channel_
* Nightly - Nightly
* Beta - Beta
* Stable稳定版 - Stable稳定版
大部分 Rust 开发者主要采用稳定版通道,不过希望实验新功能的开发者可能会使用 nightly 或 beta 版。 大部分 Rust 开发者主要采用稳定版通道,不过希望实验新功能的开发者可能会使用 nightly 或 beta 版。
@ -115,13 +114,14 @@ Rust 每 6 周发布一个版本,如时钟般准确。如果你知道了某个
### Rustup 和 Rust Nightly 的职责 ### Rustup 和 Rust Nightly 的职责
#### 安装 Rust Nightly 版本 #### 安装 Rust Nightly 版本
Rustup 使得改变不同发布通道的 Rust 更为简单,其在全局或分项目的层次工作。其默认会安装稳定版 Rust。例如为了安装 nightly Rustup 使得改变不同发布通道的 Rust 更为简单,其在全局或分项目的层次工作。其默认会安装稳定版 Rust。例如为了安装 nightly
```text ```text
$ rustup install nightly $ rustup install nightly
``` ```
你会发现 `rustup` 也安装了所有的 **工具链***toolchains* Rust 和其相关组件)。如下是一位作者的 Windows 计算机上的例子: 你会发现 `rustup` 也安装了所有的 **工具链**_toolchains_ Rust 和其相关组件)。如下是一位作者的 Windows 计算机上的例子:
```powershell ```powershell
> rustup toolchain list > rustup toolchain list
@ -131,6 +131,7 @@ nightly-x86_64-pc-windows-msvc
``` ```
#### 在指定目录使用 Rust Nightly #### 在指定目录使用 Rust Nightly
如你所见,默认是稳定版。大部分 Rust 用户在大部分时间使用稳定版。你可能也会这么做,不过如果你关心最新的功能,可以为特定项目使用 nightly 版。为此,可以在项目目录使用 `rustup override` 来设置当前目录 `rustup` 使用 nightly 工具链: 如你所见,默认是稳定版。大部分 Rust 用户在大部分时间使用稳定版。你可能也会这么做,不过如果你关心最新的功能,可以为特定项目使用 nightly 版。为此,可以在项目目录使用 `rustup override` 来设置当前目录 `rustup` 使用 nightly 工具链:
```text ```text

@ -7,6 +7,7 @@
## 在格式化字符串时捕获环境中的值 ## 在格式化字符串时捕获环境中的值
在以前,想要输出一个函数的返回值,你需要这么做: 在以前,想要输出一个函数的返回值,你需要这么做:
```rust ```rust
fn get_person() -> String { fn get_person() -> String {
String::from("sunface") String::from("sunface")
@ -18,7 +19,9 @@ fn main() {
println!("Hello, {person}!", person = p); println!("Hello, {person}!", person = p);
} }
``` ```
问题倒也不大,但是一旦格式化字符串长了后,就会非常冗余,而在 1.58 后,我们可以这么写: 问题倒也不大,但是一旦格式化字符串长了后,就会非常冗余,而在 1.58 后,我们可以这么写:
```rust ```rust
fn get_person() -> String { fn get_person() -> String {
String::from("sunface") String::from("sunface")
@ -28,16 +31,20 @@ fn main() {
println!("Hello, {person}!"); println!("Hello, {person}!");
} }
``` ```
是不是清晰、简洁了很多?甚至还可以将环境中的值用于格式化参数: 是不是清晰、简洁了很多?甚至还可以将环境中的值用于格式化参数:
```rust ```rust
let (width, precision) = get_format(); let (width, precision) = get_format();
for (name, score) in get_scores() { for (name, score) in get_scores() {
println!("{name}: {score:width$.precision$}"); println!("{name}: {score:width$.precision$}");
} }
``` ```
但也有局限,它只能捕获普通的变量,对于更复杂的类型(例如表达式),可以先将它赋值给一个变量或使用以前的 `name = expression` 形式的格式化参数。 但也有局限,它只能捕获普通的变量,对于更复杂的类型(例如表达式),可以先将它赋值给一个变量或使用以前的 `name = expression` 形式的格式化参数。
目前除了 `panic!` 外,其它接收格式化参数的宏,都可以使用新的特性。对于 `panic!` 而言,如果还在使用 `2015版本``2018版本` 版本 ,那 `panic!("{ident}")` 依然会被当成 正常的字符串来处理,同时编译器会给予 `warn` 提示。而对于 `2021版本` ,则可以正常使用: 目前除了 `panic!` 外,其它接收格式化参数的宏,都可以使用新的特性。对于 `panic!` 而言,如果还在使用 `2015版本``2018版本` 版本 ,那 `panic!("{ident}")` 依然会被当成 正常的字符串来处理,同时编译器会给予 `warn` 提示。而对于 `2021版本` ,则可以正常使用:
```rust ```rust
fn get_person() -> String { fn get_person() -> String {
String::from("sunface") String::from("sunface")
@ -49,6 +56,7 @@ fn main() {
``` ```
输出: 输出:
```console ```console
thread 'main' panicked at 'Hello, sunface!', src/main.rs:6:5 thread 'main' panicked at 'Hello, sunface!', src/main.rs:6:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
@ -57,6 +65,7 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
## 比 unwrap 更危险的 unwrap_unchecked ## 比 unwrap 更危险的 unwrap_unchecked
在 1.58 中为 `Option``Result` 新增了 `unwrap_unchecked` 方法,与 `unwrap` 遇到错误或者空值直接 `panic` 不同,`unwrap_unchecked` 遇到错误时处理方式糟糕的多: 在 1.58 中为 `Option``Result` 新增了 `unwrap_unchecked` 方法,与 `unwrap` 遇到错误或者空值直接 `panic` 不同,`unwrap_unchecked` 遇到错误时处理方式糟糕的多:
```rust ```rust
fn get_num() -> Option<i32> { fn get_num() -> Option<i32> {
None None
@ -69,6 +78,7 @@ fn main() {
``` ```
输出如下: 输出如下:
```console ```console
zsh: segmentation fault cargo run zsh: segmentation fault cargo run
``` ```

@ -1,10 +1,13 @@
# Rust 新版解读 | 1.59 | 重点: 内联汇编、解构式赋值 # Rust 新版解读 | 1.59 | 重点: 内联汇编、解构式赋值
Rust 团队于今天凌晨( 2022-02-25 )发布了最新的 1.59 版本,其中最引人瞩目的特性应该就是支持在代码中内联汇编了,一起来看看。 Rust 团队于今天凌晨( 2022-02-25 )发布了最新的 1.59 版本,其中最引人瞩目的特性应该就是支持在代码中内联汇编了,一起来看看。
## 内联汇编( inline assembly ) ## 内联汇编( inline assembly )
该特性对于需要底层控制的应用非常有用,例如想要控制底层执行、访问特定的机器指令等。 该特性对于需要底层控制的应用非常有用,例如想要控制底层执行、访问特定的机器指令等。
例如,如果目标平台是 `x86-64` 时,你可以这么写: 例如,如果目标平台是 `x86-64` 时,你可以这么写:
```rust ```rust
use std::arch::asm; use std::arch::asm;
@ -35,7 +38,9 @@ assert_eq!(x, 4 * 6);
如果大家希望深入了解,可以看官方的 [Reference](https://doc.rust-lang.org/nightly/reference/inline-assembly.html) 文档,同时在 [Rust Exercise](https://zh.exercise.rs/unsafe/inline-asm) 中提供了更多的示例(目前正在翻译中..)。 如果大家希望深入了解,可以看官方的 [Reference](https://doc.rust-lang.org/nightly/reference/inline-assembly.html) 文档,同时在 [Rust Exercise](https://zh.exercise.rs/unsafe/inline-asm) 中提供了更多的示例(目前正在翻译中..)。
## 解构式赋值( Destructuring assignments) ## 解构式赋值( Destructuring assignments)
现在你可以在赋值语句的左式中使用元组、切片和结构体模式了。 现在你可以在赋值语句的左式中使用元组、切片和结构体模式了。
```rust ```rust
let (a, b, c, d, e); let (a, b, c, d, e);
@ -51,7 +56,9 @@ assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]);
## const 泛型 ## const 泛型
#### 为参数设置默认值 #### 为参数设置默认值
现在我们可以为 const 泛型参数设置默认值: 现在我们可以为 const 泛型参数设置默认值:
```rust ```rust
struct ArrayStorage<T, const N: usize = 2> { struct ArrayStorage<T, const N: usize = 2> {
arr: [T; N], arr: [T; N],
@ -67,7 +74,9 @@ impl<T> ArrayStorage<T> {
``` ```
#### 取消参数顺序的限制 #### 取消参数顺序的限制
在之前版本中,类型参数必须要在所有的 const 泛型参数之前,现在,这个限制被放宽了,例如你可以这样交替排列它们: 在之前版本中,类型参数必须要在所有的 const 泛型参数之前,现在,这个限制被放宽了,例如你可以这样交替排列它们:
```rust ```rust
fn cartesian_product< fn cartesian_product<
T, const N: usize, T, const N: usize,
@ -82,9 +91,11 @@ where
``` ```
## 减少二进制文件体积:删除 debug 信息 ## 减少二进制文件体积:删除 debug 信息
对于受限的环境来说,减少编译出的二进制文件体积是非常重要的。 对于受限的环境来说,减少编译出的二进制文件体积是非常重要的。
在之前,我们可以在二进制文件创建后,手动的来完成。现在 cargo 和 rustc 支持在链接( linked )后就删除 debug 信息,在 `Cargo.toml` 中新增以下配置: 在之前,我们可以在二进制文件创建后,手动的来完成。现在 cargo 和 rustc 支持在链接( linked )后就删除 debug 信息,在 `Cargo.toml` 中新增以下配置:
```toml ```toml
[profile.release] [profile.release]
strip = "debuginfo" strip = "debuginfo"
@ -99,6 +110,7 @@ strip = "debuginfo"
- 最后 `opt-level = "z"` : 1,857,680 bytes - 最后 `opt-level = "z"` : 1,857,680 bytes
如果是 WASM还可以使用以下配置进一步减少体积: 如果是 WASM还可以使用以下配置进一步减少体积:
```toml ```toml
[package.metadata.wasm-pack.profile.release] [package.metadata.wasm-pack.profile.release]
wasm-opt = ['-Os'] wasm-opt = ['-Os']
@ -107,9 +119,11 @@ wasm-opt = ['-Os']
[github 上一个开源仓库](https://github.com/rsadsb/adsb_deku/blob/master/CHANGELOG.md#unreleased)也证明了这一点,总体来看,这个配置的效果是非常显著的! [github 上一个开源仓库](https://github.com/rsadsb/adsb_deku/blob/master/CHANGELOG.md#unreleased)也证明了这一点,总体来看,这个配置的效果是非常显著的!
## 默认关闭增量编译 ## 默认关闭增量编译
1.59.0 版本默认关闭了增量编译的功能(你可以通过环境变量显式地启用:`RUSTC_FORCE_INCREMENTAL=1` ),这会降低已知 Bug [#94124](https://github.com/rust-lang/rust/issues/94124) 的影响,该 Bug 会导致增量编译过程中的反序列化错误和 `panic` 1.59.0 版本默认关闭了增量编译的功能(你可以通过环境变量显式地启用:`RUSTC_FORCE_INCREMENTAL=1` ),这会降低已知 Bug [#94124](https://github.com/rust-lang/rust/issues/94124) 的影响,该 Bug 会导致增量编译过程中的反序列化错误和 `panic`
不过大家也不用担心,这个 Bug 会在 1.60.0 版本修复,也就是 6 周后,增量编译会重新设置为默认开启,如果没有意外的话 :) 不过大家也不用担心,这个 Bug 会在 1.60.0 版本修复,也就是 6 周后,增量编译会重新设置为默认开启,如果没有意外的话 :)
## 稳定化的 API 列表 ## 稳定化的 API 列表
一些方法和特征实现现在已经可以 stable 中使用,具体见[官方发布说明](https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html#stabilized-apis) 一些方法和特征实现现在已经可以 stable 中使用,具体见[官方发布说明](https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html#stabilized-apis)

@ -1,2 +1,3 @@
# 附录 GRust 更新版本列表 # 附录 GRust 更新版本列表
本目录包含了 Rust 历次版本更新的重要内容解读,需要注意,每个版本实际更新的内容要比这里记录的更多,全部内容请访问每节开头的官方链接查看。 本目录包含了 Rust 历次版本更新的重要内容解读,需要注意,每个版本实际更新的内容要比这里记录的更多,全部内容请访问每节开头的官方链接查看。

Loading…
Cancel
Save