有没有办法使Expect()输出更用户友好的消息?

时间:2018-08-10 12:24:28

标签: rust

我发现expect()产生的消息对用户来说非常不友好。考虑下面的简短示例...

use std::env;

fn main() {
    let imagefn = env::args().skip(1).next().expect("Filename not provided.");
    println!("{}", imagefn);
}

出现以下错误:

thread 'main' panicked at 'Filename not provided.', libcore/option.rs:960:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

我发现expect()对于编写快速代码非常有用,但希望我可以输出更多类似的内容:

Filename not provided.

所有其他信息都隐藏起来,除非我实际提供了环境变量,我作为开发人员应该知道这一点。我想我的问题是:

  1. 有没有办法可以覆盖expect()来做到这一点?
  2. 为什么expect()即使在发行版本中也输出其不友好的消息?

2 个答案:

答案 0 :(得分:5)

expect()只是对panic!()的方便的条件调用:

pub fn expect(self, msg: &str) -> T {
    match self {
        Some(val) => val,
        None => expect_failed(msg) // expect_failed calls panic!()
    }
}

理想情况下,您可能应该在返回?Option的函数中使用Result运算符来处理此问题,以便能够以更优美的方式处理此类问题。

如果您只想返回一条看起来更友好的消息并退出,则可以实现自己的函数,以打印消息并以process::exit结束。

答案 1 :(得分:5)

您可以使用set_hook更改紧急消息。示例:

use std::panic::set_hook;

fn main() {
    set_hook(Box::new(|info| {
        if let Some(s) = info.payload().downcast_ref::<String>() {
            println!("{}", s);
        }
    }));

    // Displays: "My error message":
    Option::None::<i32>.expect("My error message");
}

您还可以使用更简单但不稳定的message()

#![feature(panic_info_message)]

use std::panic::set_hook;

fn main() {
    set_hook(Box::new(|info| {
        println!("{:?}", info.message().unwrap());
    }));

    Option::None::<i32>.expect("My error message");
}

请注意,您可以创建自己的扩展方法,以自定义类型进行恐慌。在紧急情况挂钩中,如果您可以向下转换为自定义类型,则可以确定紧急情况的来源。