Rust异常处理

错误

错误在软件中无可否认事实,rust很多特性处理错误清晰,能够在编译代码之前采取行动,使得程序更加健壮, rust中将错误归类两种类型可恢复错误(报告错误并且重试,逻辑错误)不可恢复错误(bug)
rust 中没有异常,有可以恢复错误Resu<T> , 不可恢复错误panic!

panic! 宏

栈展开(回溯栈并且清理遇到内存)/ 终止由系统清理内存 在Cargo.toml增加panic = 'abort' 切换到终止模式

fn main() {
    panic!("crash and burn");
}
$ cargo run
   Compiling panic v0.1.0 (file:///projects/panic)
    Finished dev [unoptimized + debuginfo] target(s) in 0.25s
     Running `target/debug/panic`
thread 'main' panicked at 'crash and burn', src/main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

panic 显示出现问题地方

  • panic!的backtrace 确认bug
    backtrace: 执行到当前位置被调用函数的列表 ,JAVA中调用链关系
fn main() {
    let v = vec![1, 2, 3];

    v[99]; // 尝试越界处理, 出现panic ,C++ 中内存溢出出现安全漏洞
}

stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a\/library\std\src\panicking.rs:498
   1: core::panicking::panic_fmt
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a\/library\core\src\panicking.rs:116
   2: core::panicking::panic_bounds_check
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a\/library\core\src\panicking.rs:84
   3: core::slice::index::impl$2::index<i32>
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a\library\core\src\slice\index.rs:189
   4: core::slice::index::impl$0::index<i32,usize>
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a\library\core\src\slice\index.rs:15
   5: alloc::vec::impl$15::index<i32,usize,alloc::alloc::Global>
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a\library\alloc\src\vec\mod.rs:2520
   6: rust_helloword::main
             at .\src\main.rs:4
   7: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a\library\core\src\ops\function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\rust_helloword.exe` (exit code: 101)

Result 类型

enum Result<T, E> {
   Ok(T),
   Err(E),
}

use std::fs::File;

fn main() {
    let f = File::open("hello.txt");
    let f = match f {
        Ok(file) =>file,
        Err(error) => panic!("problem open in the file {:?}", error),
    };
}

  • z不同方式处理不同类型错误
use std::fs::File;
use std::io::ErrorKind;

fn main() {
    let f = File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(error) => match error.kind() {
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("Problem creating the file: {:?}", e),
            },
            other_error => {
                panic!("Problem opening the file: {:?}", other_error)
            }
        },
    };
}
  • 失败panic 简写 unwarp / expec
    一般采用excep 原因在于except 提供一个好的错误信息并且妙明意图更加容易对于panic跟踪
  let f = File::open("hello.txt").expect("Failed to open hello.txt");
   使用 expect 而不是 unwrap 并提供一个好的错误信息可以表明你的意图并更易于追踪 panic 的根源
  • 传播错误
    更好控制代码调用,调用者拥有更多的信息或者逻辑决定处理错误

use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let f = File::open("hello.txt");

    let mut f = match f {
        Ok(file) => file,
        Err(e) => return Err(e),
    };

    let mut s = String::new();

    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}

?运算符进行简写,?之后直接使用调用链方式进一步缩短代码,类似JS ECA6 使用? 进行调用链.
? 运算符只能被用于返回值与 ? 作用的值相兼容的函数`

 let mut s = String::new()
 File::open("hello.txt")?.read_to_string(&mut s)?;
 Ok(s)

使用场景

  • 示例代码,代码原型和测试适合使用panic
  • 别人调用你代码传递一个没有意义参数 panic,调用外部代码,并且返回了一个无法修复的无效状态使用 panic 非常合适;
  • 当错误预期会出现 使用Result 更好

新创建类似验证实例

#新创建一个新类型验证不是重复检测

// 结构体的函数
impl Guess {
    // 构造函数
    pub fn new(value: i32) -> Guess {
        if value <1 || value > 100 {
            panic!("Guess value must be between 1 and 100, got {}.", value);
        }
        Guess { value }
    }

    pub fn value(&self) -> i32 {
        self.value
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值