返回介绍

6.1 不可恢复

发布于 2024-10-13 11:25:29 字数 2660 浏览 0 评论 0 收藏 0

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文