首页 技术杂谈 正文
  • 本文约1313字,阅读需7分钟
  • 338
  • 0

Rust - panic!

摘要

Rust中的panic!,程序遇到不可恢复错误的紧急制动器。它触发时,程序会尝试安全地清理资源,然后终止执行,是Rust错误处理策略中的一种极端手段,用于处理那些无法通过常规方式恢复的异常情况。

不可恢复的错误与panic!

1、Rust的错误处理

  • Rust的可靠性:错误处理

2、错误的分类

  • 可恢复 : 如文件未找到
  • 不可恢复 : bug, 如数组越界

3、Rust没有其他语言的异常的机制

  • 对于可恢复的错误的方法: Result<T,E>
  • 对不可恢复的错误的方法: panic!宏

1、不可恢复错误

1、当panic!宏执行

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

2、为了应对展开和清理调用栈

  • 默认情况下当panic发生
    • Rust沿着调用栈往会走
    • 清理每个遇到函数中的数据
  • 或者可以立即中止调用栈
    • 不进行清理,直接停止程序
    • 后续需要OS去清理内存

3、想让二进制文件更小,就可以把展开改成中止

  • 通过修改cargo.toml文件[profile.release]
    • panic='about'

2、panic!宏的使用

1、panic!可能出现的地方

  • 自己编写代码中
  • 调用的依赖的代码中

2、可以通过panic!宏来回溯出现问题的代码

3、可以通过环境变量设置调试信息

4、在调试的时候,cargo run 必须不能使用--release

fn main() {
    panic!("出现错误了");
}

3、可恢复的错误

1、Result<T,E>枚举

enum Result<T,E>{
    Ok(T),
    Err(E),
}
// T : 表示操作成功的情况,OK变体里返回的数据的类型
// E : 表示操作失败的情况,Err变体里返回的错误的类型
use std::fs::File;
fn main() {
    // 这个返回的值就是Resule枚举类型
    let f = File::open("1.txt");
}

4、处理Result枚举的结果,使用match

use std::fs::File;

fn main() {
    // 这个返回的值就是Resule枚举类型
    let f = File::open("1.txt");

    // 处理结果
    match f {
        Ok(file) => file,
        Err(err) => panic!(
            "打开文件失败{:?}",{err})
    };
}
  • 匹配不同的错误使用kind()方法,但是里面会嵌套多个match,由此引出了unwrap
  • unwrap : match表达式的一个快捷方法
    let f = File::open("1.txt").unwrap();
  • 但是unwrap不能自定义错误信息,所以引出了另一个方法expect
    let f = File::open("1.txt").expect("无法打开文件");

5、传播错误

?运算符:用来传播错误的一种快捷方式

  • 后面加?直接就类似于执行了match里面的操作
  • 如果result是OK,OK中的值就是表达式的结果,继续执行程序
  • 如果result是Err, Err就是整个函数的返回值,就像使用了return
  • ?运算符只能作用返回结果为Result才可以使用
    fn read_username_from_file() -> Result<String,io::Error>{
    // 打开文件 后面加?直接就类似于执行了match里面的操作
    let mut f = File::open("1.txt")?;
    // 创建一个字符串
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
    }

6、总体原则

1、在定义一个可能失败的函数的时候,优先考虑返回的是Result
2、否则就panic!

评论