我正在编写一个控制台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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不会编译并产生以下错误:
error[E0381]: use of possibly uninitialized variable: `runmode`
--> src/main.rs:27:11
|
27 | match runmode {
| ^^^^^^^ use of possibly uninitialized `runmode`
Run Code Online (Sandbox Code Playgroud)
我知道有些情况下可以定义runmode,但在这些情况下,match
将永远不会到达第27行.我可以通过为runmode定义默认值来避免,但这似乎并不干净.什么是在Rust中处理这个问题的正确方法?
从编译器的角度来看,当您调用时die_with_error()
,您的函数不会向调用者返回任何值.实际上,这个函数不仅没有返回任何内容,它根本不返回.在Rust中表达它的方法是使用never类型!
:
fn die_with_error(error: &str) -> ! {
eprintln!("{}", &error);
process::exit(-1)
}
Run Code Online (Sandbox Code Playgroud)
通过此更改,编译器将知道runmode
必须始终具有初始化值.