Files
DefectingCat.github.io/content/posts/chapter-7-error-handling.mdx
2025-03-18 09:57:13 +08:00

71 lines
2.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 第 7 章 错误处理
date: '2024-12-12'
tags: [Rust]
---
Rust 中有两类常见的错误处理:`panic` 和 `Result`。
普通错误使用 `Result` 类型来处理。`Result` 通常用以表示由程序外部的事物引发的错误,比如错误的输入、网络的中断或权限问题。
`panic` 针对的是另一种错误,即那种永远不应该发生的错误。
> Rust 之所以会用一个新词panic而不是沿用“异常”来表达是因为两者并不等价。
## panic
当程序遇到下列问题时,就可以断定程序自身存在 Bug故而引发 panic
- 数组越界访问;
- 整数除以 0
- 在恰好为 `Err` 的 `Result` 上调用 `.expect()`
- 断言失败;
在 panic 时Rust 为我们提供了一种选择,展开调用栈或者终止进程。展开调用栈是默认方案。
### 展开调用栈
如果在 Rust 中除以了 0就会触发 panic通常按如下方式处理
```rust
#[allow(unconditional_panic)]
fn main() {
let x = 37 / 0;
}
```
- 把一条错误信息打印到终端。
```shell
thread 'main' panicked at main.rs:3:13:
attempt to divide by zero
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
如果设置了 `RUST_BACKTRACE=1` 环境变量那么就像这条消息打印的一样Rust 也会在这里转储当前调用栈。
```shell
RUST_BACKTRACE=1 ./main
thread 'main' panicked at main.rs:3:13:
attempt to divide by zero
stack backtrace:
0: rust_begin_unwind
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:645:5
1: core::panicking::panic_fmt
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/panicking.rs:72:14
2: core::panicking::panic
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/panicking.rs:145:5
3: main::main
4: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```
- 展开调用栈。这很像 C++ 的异常处理。
当前函数使用的任何临时值、局部变量或参数都会按照与创建它们时相反的顺序被丢弃。丢弃一个值仅仅意味着随后会进行清理:程序正在使用的任何字符串或者向量都将被释放,所有打开的文件都将被关闭,等等。还会调用由用户定义的 `drop` 方法。
清理了当前函数调用后,我们将继续执行到其调用者中,以相同的方式丢弃其变量和参数。然后再“走到”那个调用者的调用者中,在调用栈中逐级向上,以此类推。
panic 是安全的,没有违反 Rust 的任何安全规则,即使你故意在标准库方法的中间引发 panic它也永远不会在内存中留下悬空指针或半初始化的值。
panic 是基于线程的,一个线程 panic 时,其他线程可以继续做自己的事。