Error handling 应为struct Config,在使用process::exit时找到()

Error handling 应为struct Config,在使用process::exit时找到(),error-handling,rust,closures,traits,Error Handling,Rust,Closures,Traits,我对生锈和翻阅官方书籍是个新手。我正在编写一个简单的grep示例,希望制作一个exit函数,可以在不同的地方使用。不幸的是,在unwrap\u或\u else中的闭包中使用此函数会导致编译错误。我不清楚这是为什么,因为当我在闭包中直接使用函数的内容时,它会工作 这是我的main.rs文件: use std::env; use std::fs; use std::process; use std::error::Error; use std::fmt::Display; struct Confi

我对生锈和翻阅官方书籍是个新手。我正在编写一个简单的grep示例,希望制作一个
exit
函数,可以在不同的地方使用。不幸的是,在
unwrap\u或\u else
中的闭包中使用此函数会导致编译错误。我不清楚这是为什么,因为当我在闭包中直接使用函数的内容时,它会工作

这是我的
main.rs
文件:

use std::env;
use std::fs;
use std::process;
use std::error::Error;
use std::fmt::Display;

struct Config{
    query: String,
    filename: String,
}

impl Config {
    fn new(input: &[String]) -> Result<Config, &'static str> {
        if input.len() < 3 {
            return Err("Not enough arguments provided.");
        }
        let query = input[1].clone();
        let filename = input[2].clone();

        Ok(Config { query, filename })
    }
}

fn run(cfg: Config) -> Result<(), Box<dyn Error>> {
    let contents = fs::read_to_string(&cfg.filename)?;
    contents.find(&cfg.query).expect("Corrupted text file.");

    Ok(())
}

fn exit<T: Display>(msg: &str, err: T) {
    println!("{}: {}", msg, err);
    process::exit(1);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    println!("{:?}", args);

    let cfg = Config::new(&args).unwrap_or_else(|err| {
        exit("Problem parsing arguments", err);
    });
    
    if let Err(err) = run(cfg) {
        exit("Application error", err);
    }
}

当我将
Config::new(&args).unwrap\u或_else
闭包更改为此时,它会起作用:

let cfg = Config::new(&args).unwrap_or_else(|err| {
    println!("Problem parsing arguments: {}", err);
    process::exit(1);
});

您需要指定您的
exit()
函数永远不会返回,即添加
->

这些函数称为“”

fn退出(消息:&str,错误:T)->!{
println!(“{}:{}”,msg,err);
过程::退出(1);
}
但是,您应该小心使用。因为它将终止当前进程,并且不会调用析构函数。

为了确保析构函数得到处理,您应该执行以下操作:

fn main() {
    std::process::exit(match run() {
        Ok(_) => 0,
        Err(code) => code,
    });
}

fn run() -> Result<(), i32> {
    // Application logic here, i.e. what you'd otherwise have had in `main()`

    Ok(())
}
fn main(){
std::process::exit(匹配运行(){
正常()=>0,
错误(代码)=>代码,
});
}
fn run()->结果{
//这里的应用程序逻辑,即在`main()`
好(())
}
该示例是在文档中找到的一个小版本。

要添加到这个更为惯用的版本中,它不使用
process::exit

使用std::env;
使用std::error::error;
使用std::fmt::Display;
使用std::fs;
使用std::过程;
结构配置{
查询:字符串,
文件名:String,
}
impl配置{

fn新建(输入:&[String])->Result@mcarton关于析构函数的一点很好,我已经更新了答案,包括:)@vallentin Now I'm happy:)。虽然在一个设计良好的程序中,错误类型的
Display
实现可能会解决这个问题。还有类似于“”.然而,它使用的特点是只在夜间使用。