error-handling - 预期的struct Config,在使用process::exit时找到()

标签 error-handling rust closures traits

我是Rust的新手,正在阅读正式书。我正在研究一个简单的grep示例,并想制作一个exit函数,可以在不同的地方使用。不幸的是,在unwrap_or_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);
    }
}

这是编译错误:
error[E0308]: mismatched types
  --> src\main.rs:41:55
   |
41 |       let cfg = Config::new(&args).unwrap_or_else(|err| {
   |  _______________________________________________________^
42 | |         exit("Problem parsing arguments", err);
43 | |     });
   | |_____^ expected struct `Config`, found `()`
当我将Config::new(&args).unwrap_or_else闭包更改为此时,它可以工作:
let cfg = Config::new(&args).unwrap_or_else(|err| {
    println!("Problem parsing arguments: {}", err);
    process::exit(1);
});

最佳答案

您需要指定exit()函数永不返回,即添加-> !
这些功能称为“diverging functions”。

fn exit<T: Display>(msg: &str, err: T) -> ! {
    println!("{}: {}", msg, err);
    process::exit(1);
}
但是,使用 process::exit() 时应格外小心。因为它将终止当前进程,所以不会调用析构函数。
为了确保处理析构函数,您应该改为执行以下操作:
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(())
}
该示例是 process::exit() 文档中找到的版本的较小改编版本。

关于error-handling - 预期的struct Config,在使用process::exit时找到(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65980128/

相关文章:

asp.net-mvc - 如何防止剑道调度程序关闭窗口

rust - 在模块中派生可编码特征不起作用

arrays - 从数组取消大小时,Rust如何确定切片的长度?

javascript - 了解 v8 中的 javascript 闭包变量捕获

rust - 无法计算出从捕获成员变量的方法返回的闭包

Swift 中的 C# 异步等待

perl - 在 Perl 中将 CSV 中的一行读入 Hash 中最抗错误的方法是什么?

c - 使用C中的fgets()函数检测到堆栈崩溃

rust - 在 Rust 中实现 PHP array_column

javascript - 异步/等待错误处理