文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
6.1 不可恢复
宏 panic!
主要用于测试,以及不可恢复性(unrecoverable)错误。
不可恢复性错误通常是代码缺陷(bug),以及系统故障等不该发生的事件。
panic!
接受和print!
相同的格式化参数构建错误信息。
显示错误信息,展开(unwinding)调用堆栈,逐级向外回溯并清理数据,终止线程或进程。
struct X { n: i32, } impl Drop for X { fn drop(&mut self) { println!("Dropping {}!", self.n); } } fn test() { let _x = X{n: 2}; panic!("panic test."); } fn main() { let _y = X{n: 1}; test() }
$ cargo r thread 'main' panicked at 'panic test.', src/main.rs:13:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Dropping 2! Dropping 1!
$ RUST_BACKTRACE=1 cargo r thread 'main' panicked at 'panic test.', src/main.rs:13:5 stack backtrace: 0: std::panicking::begin_panic at /rustc/.../panicking.rs:519:12 1: demo::test at ./src/main.rs:13:5 2: demo::main at ./src/main.rs:18:5 3: core::ops::function::FnOnce::call_once at /rustc/.../function.rs:227:5 note: run with `RUST_BACKTRACE=full` for a verbose backtrace. Dropping 2! Dropping 1!
捕获 panic,仅适合调试或测试。
use std::panic::catch_unwind; fn test() { panic!("error"); } fn main() { let r = catch_unwind(||{ test(); }); println!("exit: {:?}.", r); }
$ cargo r Compiling demo v0.1.0 (/root/.mac/rs/demo) Finished dev [unoptimized + debuginfo] target(s) in 10.99s Running `target/debug/demo` thread 'main' panicked at 'error', src/main.rs:10:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace exit: Err(Any).
可在 Cargo.toml 中设置以终止(abort)代替展开,不回溯清理,直接终止进程。
对于部署的发行版(release version),展开信息可能没什么用。
还可删除符号表(strip),避免错误信息造成泄密。
# Cargo.toml [profile.release] panic = 'abort'
$ cargo r --release Finished release [optimized] target(s) in 0.09s Running `target/release/demo` thread 'main' panicked at 'panic test.', src/main.rs:13:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Aborted
常见场景
除直接调用外,以下场景也会引发 panic! 错误。
- 越界访问。
- 被除以零。
- 断言失败。
Option<T>.unwrap
/expect
。Result<T>.unwrap
/expect
。
分歧函数
分歧函数(diverging)表示永远不会返回(never return)的函数。
- 无限循环(运行时等启动函数)。
- 包装
panic!
,用于调试或跟踪调用堆栈。 - 紧急终止进程。
虽然不会有结果,但可用于任何类型赋值。
fn test() -> ! { panic!("This function never returns!"); } fn main() { let _x = test(); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论