error-handling - 捕获 panic 的正确方法是什么?

标签 error-handling rust

我们经常不希望我们的程序由于越界、被 0 除或类似的 panic 而停止。然而,std::thread::catch_panic 被标记为不稳定。我们可以写...

let result = Thread::scoped(move || {
        make_a_division_for_ever()
    }).join();
    if result.is_ok() {
        println!("Finished OK");
    }

这是捕捉 panic 的正确方法吗(比如除以 0 或越界)?

一个完整的例子...

use std::thread::Thread;

fn main() {
    println!("Make divisions for ever");

    loop {
        let result = Thread::scoped(move || {
            make_a_division_for_ever()
        }).join();
        if result.is_ok() {
            println!("Finished OK");
        }
        else {
            println!("It CRASHED!!!  restarting...");
        }
    }

}

fn make_a_division_for_ever() {
    loop {
        println!("Enter divisor...");
        let line = std::io::stdin()
                .read_line()
                .ok()
                .expect("error reading line");

        let divisor = line.trim()
                .parse::<u32>()
                .expect("
I coudn't parse your line as an string. I'm going to die
I showed things closer than orion belt...
        ");

        println!("readed {}", divisor);

        let dangerous =  1_000_000 / divisor;

        println!("DIV RESULT... {}", dangerous);
    }
}

最佳答案

在大多数情况下,Rust panic 并不打算被捕获。 Unstable Rust 提供了这个功能,但是你应该只在你遇到非常复杂的情况时才使用它(比如,你正在为其他 Rust 程序编写测试工具并且需要 Hook 到 panic 处理程序)而你不能冒泡错误。

在 Rust 中,错误处理是通过返回 Result<T,E> 来完成的s(有时 Option<T> ,用 try!() 冒泡它们,然后用 match 处理它们。

大多数 panicky 方法都有非 panicky 版本;例如,divide 的检查版本是 checked_div() , 你可以使用 try!返回字符串解析的错误。

关于error-handling - 捕获 panic 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30232890/

相关文章:

javascript - 尝试可以正常工作,但Catch在Javascript函数中不起作用,如下所述

php - 错误处理-如何捕捉?

enums - 如何在没有模式匹配的情况下比较枚举

generics - 无法访问动态特征实现中的结构字段

c# - 在多个例程之间使用try-catch

c# - 可以将 catch block 的结果传递给 try block 内的方法吗?

php - 有没有办法遍历一组已发布的变量,检查它们是否已设置?

rust - 原地插入 Rust 数组,将其他元素向下推

rust - 当从 Xcode 8 内部运行时,由于信号 10, cargo 无法与 `cc` 链接

rust - 为什么 Rust 编译器在移动对象后不重用堆栈上的内存?