Rust 错误处理概述

  • Rust 的可靠性:错误处理
    • 大部分情况下:在编译时提示错误,并处理
  • 错误分类:
    • 可恢复
      • 例如文件未找到,可再次尝试
    • 不可恢复
      • bug,例如访问的索引超出返回
  • Rust 没有类似异常的机制

    • 可恢复错误:Result
    • 不可恢复:panic! 宏

      panic!

  • 当 panic! 宏执行:

    • 程序会打印一个错误信息
    • 展开 ( unwind )、清理调用栈 ( Stack )
    • 退出程序

      为应对 panic,默认是展开或手动中止(abort)调用栈

  • 默认情况下,当 panic 发生:

    • 程序展开调用栈(工作量大)
      • Rust 沿着调用栈往回走
      • 清理每个遇到的函数中的数据
    • 或立即中止调用栈:
      • 不进行清理,直接停止程序
      • 内存需要 OS 进行清理
  • 想让二进制文件更小,把设置从“展开”改为“中止”:
    • 在 Cargo.toml 中适当的 profile 部分设置:
      • panic=’abort’ ``` [package] name = “demo” version = “0.1.0” authors = [“custer-go custertian@163.com“] edition = “2018”

See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[profile.release] panic = ‘abort’

  1. <a name="Q16Ox"></a>
  2. ### 使用 panic! 产生的回溯信息
  3. - panic! 可能出现在:
  4. - 我们写的代码中
  5. - 我们所依赖的代码中
  6. - 可通过调用 panic! 的函数的回溯信息来定位引起问题的代码
  7. ```rust
  8. fn main() {
  9. panic!("Crash and burn");
  10. }

运行查看报错信息

  1. thread 'main' panicked at 'Crash and burn', src/main.rs:2:5
  2. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  1. fn main() {
  2. let v = vec![1, 2, 3];
  3. v[99];
  4. }

报错信息

  1. thread 'main' panicked at 'index out of bounds:
  2. the len is 3 but the index is 99', src/main.rs:4:5
  3. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  • 通过设置环境变量 RUST_BACKTRACE 可得到回溯信息

linux 运行 export RUST_BACKTRACE=1 && cargo run
windows 运行 set RUST_BACKTRACE=1 && cargo run

  1. > export RUST_BACKTRACE=1 && cargo run
  2. Finished dev [unoptimized + debuginfo] target(s) in 0.01s
  3. Running `target/debug/string`
  4. thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:4:5
  5. stack backtrace:
  6. 0: rust_begin_unwind
  7. at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
  8. 1: core::panicking::panic_fmt
  9. at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:92:14
  10. 2: core::panicking::panic_bounds_check
  11. at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:69:5
  12. 3: <usize as core::slice::index::SliceIndex<[T]>>::index
  13. at /Users/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/index.rs:182:10
  14. 4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
  15. at /Users/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/index.rs:15:9
  16. 5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
  17. at /Users/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/vec.rs:2161:9
  18. 6: string::main
  19. at ./src/main.rs:4:5
  20. 7: core::ops::function::FnOnce::call_once
  21. at /Users/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
  22. note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
  • 为了获取带有调式信息的回溯,必须启用调式符号(不带 —release)