在匹配"结果"并仍然能够捕获错误时使用if-let绑定的惯用方法是什么?

Del*_*ore 2 rust

fn lines_from_file<F>(filename: F) -> Result<io::Lines<BufReader<File>>, io::Error>
where
    F: std::convert::AsRef<std::path::Path>,
{
    let file = File::open(filename)?;
    Ok(io::BufReader::new(file).lines())
}

fn main() {
    let filename: &str = "input.pdl";
    // This works fine
    match lines_from_file(filename) {
        Ok(lines) => {
            for line in lines {
                println!("{:?}", line);
            },
        }
        Err(e) => println!("Error {:?}", e),
    }
}
Run Code Online (Sandbox Code Playgroud)

我想改用它:

if let lines = Ok(lines_from_file(filename)) {
    for line in lines {
        println!("{:?}", line);
    }
} else {
    println!("Error {:?}" /*what goes here?*/,)
}
Run Code Online (Sandbox Code Playgroud)

但这给出了一个错误:

| if let lines = Ok(lines_from_file(filename)) {
|                ^^ cannot infer type for `E`
Run Code Online (Sandbox Code Playgroud)

在匹配a Result并仍然能够捕获错误时使用if-let绑定的惯用方法是什么?

Luk*_*odt 9

[...]在匹配结果时仍然能够捕获错误时使用if-let绑定?

从根本上说这是不可能的if let.该if let构造体的唯一目的是为了让生活在你只想解构一个模式的情况下更容易.如果你想要解构a的两个案例Result,你必须使用match(或多个if letunwrap(),但这不是一个好的解决方案).为什么你不想match在第一时间使用?

关于编译错误:你添加Ok()了错误的一面:

if let Ok(lines) = lines_from_file(filename) { ... }
Run Code Online (Sandbox Code Playgroud)

这是使用的正确方法if let:左侧的解构模式,表达式向右生成值.

  • @Ronnie它会工作,但当然,你不会打印任何有关错误的信息.所以我建议你在第一个例子中使用`match`. (3认同)