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

时间:2017-11-12 12:06:20

标签: 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),
    }
}

我想改用它:

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

但这会产生错误:

| if let lines = Ok(lines_from_file(filename)) {
|                ^^ cannot infer type for `E`

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

1 个答案:

答案 0 :(得分:7)

  

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

一个if let根本不可能。 if let构造的唯一目的是在您只想构造一个模式的情况下使生活更轻松。如果您要对Result的两种情况进行解构,则必须使用match(或多个if letunwrap(),但这不是一个好的解决方案。为什么你不想首先使用match

关于编译器错误:您在错误的一侧添加了Ok()

if let Ok(lines) = lines_from_file(filename) { ... }

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