预期的结构配置,在使用 process::exit 时找到 ()

Expected struct Config, found () while using process::exit

我是 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() 函数从不 returns,即添加 -> !.

这些函数称为“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().

文档中的版本的次要改编版本

要添加到 ,这里是不使用 process::exit 的更惯用的版本:

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

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)?;
    // convert Option to a Result so we can use `?`
    contents.find(&cfg.query).ok_or("Corrupted text file.")?;
    Ok(())
}

// you can return a Result from main and Rust will
// print the error to the user if there is one
fn main() -> Result<(), Box<dyn Error>> {
    let args: Vec<String> = env::args().collect();
    println!("{:?}", args);

    // use `?` instead of `exit` function
    let cfg = Config::new(&args)?;
    run(cfg)?;
    Ok(())
}

playground

我也卡在这上面了。您需要导入流程库:

use std::process;

编辑:再看一眼,您确实导入了它。对于 运行 遇到这个问题的其他人来说,那是我的问题。我得到了同样的错误。