匹配特定的错误类型

时间:2015-02-13 02:54:48

标签: error-handling rust

我试图在一个文件中读取,直到每次结束2个字节。我想抓住EOF错误。我有这段代码:

loop {
    let binary = match file.read_be_u16() {
        Ok(binary) => binary,
        Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
                  // Can I catch this EOF error here?
    };
    println!("{:?}", binary);
}

5 个答案:

答案 0 :(得分:9)

至少rustc版本rustc 1.17.0(56124baa9 2017-04-24)不允许解构Chris Morgan的答案使用的Err。我发现这个工作:

Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => true,
Err(e) => { println!("{:?}", e); false }
Ok(_) => false,

答案 1 :(得分:6)

您可以使用模式匹配的一些更高级功能将类型作为模式的一部分进行匹配:

Err(IoError { kind: IoErrorKind::EndOfFile, .. }) => break,
Err(e) => panic!("Can't read from file: {}, err {}", filename, e),

第一种变体意味着“Err包含IoError,其中kindIoErrorKind::EndOfFile,而所有其他字段都是您喜欢的”。第二个则表示“任何其他Err,将包含的值绑定到变量名称e”。

答案 2 :(得分:3)

成为Rust的新手我并不太了解“生锈”的做事方式(所以不确定这是否会让人气馁)但我个人觉得...

Ok(binary) => binary,
Err(e) => match e.kind() {
    EndOfFile => break,
    [..SomeOtherError..] => do_something(),
    _ => panic!("Can't read from file: {}, err {}", filename, e),
},

......比...更具可读性。

Ok(binary) => binary,
Err(ref e) if e.kind() == EndOfFile => break,
Err(ref e) if e.kind() == [..SomeOtherError..] => do_something(),
Err(e) => panic!("Can't read from file: {}, err {}", filename, e),

(不确定我们可以期待的其他错误......)

显然,在比赛警卫可能不一样的其他情况下 - 我们重复e.kind()的方式 - 我们无法使用嵌套的match

注意:rustc 1.25.0 (84203cac6 2018-03-25)

起作用

答案 3 :(得分:0)

我明白了。我改变了这一行来检查错误类型!希望这有助于其他人。

Err(e) => if e.kind == IoErrorKind::EndOfFile { break } else { panic!("Can't read from file: {}, err {}", filename, e) },

答案 4 :(得分:0)

以下是匹配MySQL IoError的示例:

match pool.prep_exec("SELECT SLEEP(10)", ()) {
    Ok(_) => (),
    Err(mysql::Error::IoError(e)) => {
        eprintln!("IoError: {}", e);
        do_something();
    }
    Err(e) => {
        eprintln!("{}", e);
        return;
    }
}