避免在“匹配”结构中使用“可能使用未初始化的变量”,当在Rust中未定义变量时该结构将无法访问

时间:2018-10-01 23:54:17

标签: rust

我正在编写一个控制台Rust应用程序。它采用第一个参数,并决定要在哪种模式下运行。如果第一个参数未定义或未知,则应用程序应退出。这是代码:

use std::env;
use std::process;

enum RunMode {
    Extract,
}

fn die_with_error(error: &str) {
    eprintln!("{}", &error);
    process::exit(-1);
}

fn main() {
    let mut args = env::args();
    args.next();
    let mut runmode;

    match args.next() {
        Some(arg) => {
            match arg.as_ref() {
                "extract" => runmode = RunMode::Extract,
                _ => die_with_error(&format!("Unknown mode {}", &arg.to_string())),
            };
        }
        None => die_with_error("No mode specified. Please specify a mode as a first argument. Use --help to get a list of modes available"),
    };

    match runmode {
        RunMode::Extract => {
            let file_name = args
                .next()
                .expect("Please specify a filename as a second argument");
            println!("You passed {}", file_name);
        }
    }
}

这不能编译并产生以下错误:

error[E0381]: use of possibly uninitialized variable: `runmode`
  --> src/main.rs:27:11
   |
27 |     match runmode {
   |           ^^^^^^^ use of possibly uninitialized `runmode`

我知道在某些情况下无法定义运行模式,但是在这种情况下,永远不会到达带有match的第27行。 我可以通过为runmode定义默认值来避免这种情况,但这似乎并不干净。在Rust中解决此问题的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

从编译器的角度来看,当您调用die_with_error()时,您的函数不会向调用方返回任何值。实际上,此函数不仅不返回任何内容,也不返回任何内容。用Rust never type !表示这种方式:

fn die_with_error(error: &str) -> ! {
    eprintln!("{}", &error);
    process::exit(-1)
}

通过此更改,编译器将知道runmode必须始终具有初始化值。