From ed60697bd867d9cb5b52dc089f2d8c3c6d32b9f8 Mon Sep 17 00:00:00 2001 From: sunface Date: Thu, 10 Feb 2022 09:33:54 +0800 Subject: [PATCH] add try!, update errors --- book/contents/SUMMARY.md | 6 +---- book/contents/advance/errors.md | 1 + book/contents/advance/errors/intro.md | 1 - book/contents/advance/errors/panic-codes.md | 11 -------- book/contents/advance/errors/pretty-format.md | 1 - book/contents/advance/errors/simplify.md | 1 - book/contents/advance/errors/user-define.md | 1 - book/contents/basic/result-error/result.md | 26 ++++++++++++++++++- 8 files changed, 27 insertions(+), 21 deletions(-) create mode 100644 book/contents/advance/errors.md delete mode 100644 book/contents/advance/errors/intro.md delete mode 100644 book/contents/advance/errors/panic-codes.md delete mode 100644 book/contents/advance/errors/pretty-format.md delete mode 100644 book/contents/advance/errors/simplify.md delete mode 100644 book/contents/advance/errors/user-define.md diff --git a/book/contents/SUMMARY.md b/book/contents/SUMMARY.md index fd5565a5..99d221cc 100644 --- a/book/contents/SUMMARY.md +++ b/book/contents/SUMMARY.md @@ -83,11 +83,7 @@ - [基于Send和Sync的线程安全](advance/concurrency-with-threads/send-sync.md) - [实践应用:多线程Web服务器 todo](advance/concurrency-with-threads/web-server.md) - [全局变量](advance/global-variable.md) - - [错误处理 doing](advance/errors/intro.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) + - [错误处理](advance/errors.md) ## 专题内容,每个专题都配套一个小型项目进行实践 diff --git a/book/contents/advance/errors.md b/book/contents/advance/errors.md new file mode 100644 index 00000000..eadde0d2 --- /dev/null +++ b/book/contents/advance/errors.md @@ -0,0 +1 @@ +# 错误处理 \ No newline at end of file diff --git a/book/contents/advance/errors/intro.md b/book/contents/advance/errors/intro.md deleted file mode 100644 index a27f18e2..00000000 --- a/book/contents/advance/errors/intro.md +++ /dev/null @@ -1 +0,0 @@ -# 错误处理 diff --git a/book/contents/advance/errors/panic-codes.md b/book/contents/advance/errors/panic-codes.md deleted file mode 100644 index 1e3e8c21..00000000 --- a/book/contents/advance/errors/panic-codes.md +++ /dev/null @@ -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 会按照补码循环溢出(*two’s complement wrapping*)的规则处理。简而言之,大于该类型最大值的数值会被补码转换成该类型能够支持的对应数字的最小值。比如在 `u8` 的情况下,256 变成 0,257 变成 1,依此类推。程序不会 panic,但是该变量的值可能不是你期望的值。依赖这种默认行为的代码都应该被认为是错误的代码。 -> \ No newline at end of file diff --git a/book/contents/advance/errors/pretty-format.md b/book/contents/advance/errors/pretty-format.md deleted file mode 100644 index 5020fa72..00000000 --- a/book/contents/advance/errors/pretty-format.md +++ /dev/null @@ -1 +0,0 @@ -# 让错误展示更优雅 diff --git a/book/contents/advance/errors/simplify.md b/book/contents/advance/errors/simplify.md deleted file mode 100644 index c0a95e2e..00000000 --- a/book/contents/advance/errors/simplify.md +++ /dev/null @@ -1 +0,0 @@ -# 简化错误处理 diff --git a/book/contents/advance/errors/user-define.md b/book/contents/advance/errors/user-define.md deleted file mode 100644 index b691927e..00000000 --- a/book/contents/advance/errors/user-define.md +++ /dev/null @@ -1 +0,0 @@ -# 自定义错误 diff --git a/book/contents/basic/result-error/result.md b/book/contents/basic/result-error/result.md index db23cb25..50215deb 100644 --- a/book/contents/basic/result-error/result.md +++ b/book/contents/basic/result-error/result.md @@ -290,7 +290,7 @@ fn first(arr: &[i32]) -> Option<&i32> { - `xxx()?.yyy()?;` #### 带返回值的main函数 -因为刚才讲的 `?` 使用限制,这段代码你很容易看出它无法编译: +在了解了 `?` 的使用限制后,这段代码你很容易看出它无法编译: ```rust use std::fs::File; @@ -316,6 +316,30 @@ fn main() -> Result<(), Box> { 至于 `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 的高级进阶内容,正式开启你的高手之路。