rust 在处理带有死机的Err时,匹配臂具有不兼容的类型

umuewwlo  于 2023-10-20  发布在  其他
关注(0)|答案(3)|浏览(99)

我有一小段代码,我想用它来记录错误,如果函数失败,我会恐慌,但我似乎不能让它工作,因为我得到了“匹配武器有不兼容的类型.”错误。
我知道我应该提供这些值,但是有没有办法不这样做,因为我们无论如何都很恐慌?
或者也许有其他的方法?我试图记录一个错误,并使用.expect只恐慌,但不产生一个合适的日志或不做任何其他仪器,我们需要的。

// this is in my instrumentation crate
pub fn handle_error(panic_msg: &str, process: &str, status: &str, error: Box<dyn Error>) {
    event!(Level::ERROR, process=process, status=status, error);
    panic!("{}", panic_msg);
}
fn main() {
   let (val1, val2, val3) = match function_call(user_id).await {
        Ok(x) => x,
        Err(e) => instrumentation::handle_error("panic", "proc", "failed", Box::new((e))),
    };
}
h6my8fg2

h6my8fg21#

如果你想告诉你的消费者instrumentation::handle_error永远不会返回,你可以通过告诉它返回类型是!(称为never类型)来表达。此类型可以强制转换为任何其他类型。将hande_error改为:

pub fn handle_error(
    panic_msg: &str,
    process: &str,
    status: &str,
    error: Box<dyn Error>,
) -> ! {
    event!(Level::ERROR, process=process, status=status, error);
    panic!("{}", panic_msg)
}

恐慌是Rust中发散的一种形式,在类型系统中表示为返回“never”类型,拼写为!(无限循环也是如此)。这将使你的匹配语句编译,你将不必改变任何东西。

mitkmikd

mitkmikd2#

你只需要告诉编译器handle_error()函数永远不会返回。它的返回类型应该指定为-> !
那么编译器就不会尝试确保match语句的两个分支具有相同的类型。
这种情况(涉及match)在 The Rust Programming Language 中描述。

fn try_but_fail(
) -> std::result::Result<(i32, i32, i32), Box<dyn std::error::Error>> {
    Err("Sorry")?
}

fn handle_error(error: Box<dyn std::error::Error>) -> ! {
    panic!("ERROR: {:?}", error);
}

fn main() {
    let (val1, val2, val3) = match try_but_fail() {
        Ok(x) => x,
        Err(e) => handle_error(e),
    };
    println!("{} {} {}", val1, val2, val3);
}
/*
$ cargo run 
thread 'main' panicked at 'ERROR: "Sorry"', src/main.rs:7:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
*/
mrfwxfqh

mrfwxfqh3#

.或者你可以重构main并删除match

fn main() {
   let rslt = function_call(user_id).await;
   let Ok(x) = rslt else {
        instrumentation::handle_error("panic", "proc", "failed", Box::new((rslt.err().unwrap())));
   }
}

相关问题