您的当前位置:首页正文

The Rust Programming Language - 第9章 错误处理 - 9.1 panic与不可恢复的错误

2024-11-30 来源:个人技术集锦

9 错误处理

Rust对可靠性的执着也伸到了错误处理

Rust将错误组合成两个主要的类别:可恢复错误和不可恢复错误

大多数语言并不区分这两类错误,并采用类似异常这样的方式统一处理它们,Rust没有异常,但是有可恢复的错误Rust<T,E>,和不可恢复的错误panic

9.1 panic与不可恢复的错误

Rust有panic!宏。当执行它时,程序会打印一个错误信息,展开并清理栈数据,接着退出。这种方式适用于程序出现了我们不知道如何处理的错误

对应panic时的栈展开终止

当程序遇到panic时,程序默认会开始展开,这意味着Rust会回溯并清理它遇到的每个函数的数据,但这个清理过程有很多工作,另一种方式是直接终止,清理工作由操作系统来完成。如果你需要项目的最终二进制文件越小越好,通过在Cargo.toml的[profile]部分增加panic = ‘abort’,可以由展开切换为终止。例如你想要在release模式中panic时直接终止

[profile.release]
panic = 'abort'

调用一个panic!

fn main() {
    panic!("crash and burn");
}
//
thread 'main' panicked at 'crash and burn', src/main.rs:2:5
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/std/src/panicking.rs:541:12
   1: vectors::main
             at ./src/main.rs:2:5
   2: core::ops::function::FnOnce::call_once
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
终端进程“cargo 'run', '--package', 'vectors', '--bin', 'vectors'”已终止,退出代码: 101。

根据运行结果我们发现出错在第二行的第五个字符

使用panic!的backtrace

let v = vec![1,2,3];
    let x = v[99];
//
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:3:17
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

程序运行时会输出错误信息

但是你可能看到类似以下的输出:这是因为backtrace,backtrace是执行到目前位置所有被调用的函数列表,阅读backtrace的关键是从头开始读直到发现你编写的文件,这一行往上是你的代码所调用的代码,往下则是调用你的代码的代码。这些可能包含核心的rust代码,标准库代码或用到的trace代码。将RUST_BACKTRACE环境变量设置为任何不是0的值来获取backtrace

 Finished dev [unoptimized + debuginfo] target(s) in 1.24s
     Running `target/debug/vectors`
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:3:17
stack backtrace:
   0: rust_begin_unwind
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/panicking.rs:92:14
   2: core::panicking::panic_bounds_check
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/panicking.rs:69:5
   3: <usize as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/slice/index.rs:184:10
   4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/slice/index.rs:15:9
   5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/alloc/src/vec/mod.rs:2432:9
   6: vectors::main
             at ./src/main.rs:3:17
   7: core::ops::function::FnOnce::call_once
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

这儿有很多输出,但你看到的结果可能因操作系统或Rust版本不同而不同。为了获取带有这些信息的backtrace,必须启用debug标识,当不使用 – release参数运行cargo build 或 cargo run时debug标识会默认启用,就像这里一样

backtrace 的6行指出了我们项目中造成问题的行,修复这个panic的方法是不要在只包含三个项的vector中请求索引是100的元素

显示全文