add try!, update errors

pull/394/head
sunface 3 years ago
parent 751574adc7
commit ed60697bd8

@ -83,11 +83,7 @@
- [基于Send和Sync的线程安全](advance/concurrency-with-threads/send-sync.md) - [基于Send和Sync的线程安全](advance/concurrency-with-threads/send-sync.md)
- [实践应用多线程Web服务器 todo](advance/concurrency-with-threads/web-server.md) - [实践应用多线程Web服务器 todo](advance/concurrency-with-threads/web-server.md)
- [全局变量](advance/global-variable.md) - [全局变量](advance/global-variable.md)
- [错误处理 doing](advance/errors/intro.md) - [错误处理](advance/errors.md)
- [简化错误处理 todo](advance/errors/simplify.md)
- [自定义错误 todo](advance/errors/user-define.md)
- [让错误输出更优雅 todo](advance/errors/pretty-format.md)
- [会导致panic的代码 todo](advance/errors/panic-codes.md)
<!-- - [高阶特征约束(HRTB) todo](advance/hrtb.md) --> <!-- - [高阶特征约束(HRTB) todo](advance/hrtb.md) -->
## 专题内容,每个专题都配套一个小型项目进行实践 ## 专题内容,每个专题都配套一个小型项目进行实践

@ -1,11 +0,0 @@
# 会导致panic的代码
String slice range indices must occur at valid UTF-8 character boundaries. If you attempt to create a string slice in the middle of a multibyte character, your program will exit with an error. For the purposes of introducing string slices, we are assuming ASCII only in this section; a more thorough discussion of UTF-8 handling is in the “Storing UTF-8 Encoded Text with Strings” section of Chapter 8.
>
> 比方说有一个 `u8` ,它可以存放从 0 到 255 的值。那么当你将其修改为范围之外的值,比如 256则会发生**整型溢出**。关于这一行为 Rust 有一些有趣的规则。当在 debug 模式编译时Rust 会检查整型溢出若存在这些问题则使程序在编译时 *panic*。Rust 使用这个术语来表明程序因错误而退出。 [该章节](../../errors/panic.md)会详细介绍 panic。
>
> 在当使用 `--release` 参数进行 release 模式构建时Rust **不**检测溢出。相反当检测到整型溢出时Rust 会按照补码循环溢出(*twos complement wrapping*)的规则处理。简而言之,大于该类型最大值的数值会被补码转换成该类型能够支持的对应数字的最小值。比如在 `u8` 的情况下256 变成 0257 变成 1依此类推。程序不会 panic但是该变量的值可能不是你期望的值。依赖这种默认行为的代码都应该被认为是错误的代码。
>

@ -1 +0,0 @@
# 让错误展示更优雅

@ -290,7 +290,7 @@ fn first(arr: &[i32]) -> Option<&i32> {
- `xxx()?.yyy()?;` - `xxx()?.yyy()?;`
#### 带返回值的main函数 #### 带返回值的main函数
因为刚才讲的 `?` 使用限制,这段代码你很容易看出它无法编译: 在了解了 `?` 的使用限制后,这段代码你很容易看出它无法编译:
```rust ```rust
use std::fs::File; use std::fs::File;
@ -316,6 +316,30 @@ fn main() -> Result<(), Box<dyn Error>> {
至于 `main` 函数可以有多种返回值,那是因为实现了 [std::process::Termination](https://doc.rust-lang.org/std/process/trait.Termination.html) 特征,目前为止该特征还没进入稳定版 Rust 中,也许未来你可以为自己的类型实现该特征! 至于 `main` 函数可以有多种返回值,那是因为实现了 [std::process::Termination](https://doc.rust-lang.org/std/process/trait.Termination.html) 特征,目前为止该特征还没进入稳定版 Rust 中,也许未来你可以为自己的类型实现该特征!
#### try!
`?` 横空出世之前( Rust 1.13 )Rust 开发者还可以使用 `try!` 来处理错误,该宏的大致定义如下:
```rust
macro_rules! try {
($e:expr) => (match $e {
Ok(val) => val,
Err(err) => return Err(::std::convert::From::from(err)),
});
}
```
简单看一下与 `?` 的对比:
```rust
// `?`
let x = function_with_error()?; // 若返回 Err, 则立刻返回;若返回 Ok(255),则将 x 的值设置为 255
// `try!()`
let x = try!(function_with_error());
```
可以看出 `?` 的优势非常明显,何况 `?` 还能做链式调用。
总之,`try!` 作为前浪已经死在了沙滩上,**在当前版本中,我们要尽量避免使用 try! **
至此Rust 的基础内容学习已经全部完成,下面我们将学习 Rust 的高级进阶内容,正式开启你的高手之路。 至此Rust 的基础内容学习已经全部完成,下面我们将学习 Rust 的高级进阶内容,正式开启你的高手之路。

Loading…
Cancel
Save