rust 如何匹配特定的io::错误类型?

wwwo4jvm  于 2023-01-05  发布在  其他
关注(0)|答案(5)|浏览(175)

我试图读入一个文件,直到结束2字节的时间,我想捕捉EOF错误:

use byteorder::{BigEndian, ReadBytesExt}; // 1.3.4
use std::fs::File;

fn main() {
    let filename = "/etc/hosts";
    let mut file = File::open(filename).expect("Cannot open file");
    loop {
        let binary = match file.read_u16::<BigEndian>() {
            Ok(binary) => binary,
            Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
            // Can I catch the EOF error here?
        };
        println!("{:?}", binary);
    }
}
cl25kdpy

cl25kdpy1#

这在Rust 1.17.0版(可能回到Rust 1.0)中有效:

let binary = match file.read_u16::<BigEndian>() {
    Err(ref e) if e.kind() == std::io::ErrorKind::UnexpectedEof => break,
    Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
    Ok(binary) => binary,
};
lstz6jyr

lstz6jyr2#

我发现...

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
此功能适用于 rust 1.25。

31moq8wy

31moq8wy3#

编者按:此代码示例来自Rust 1.0之前的版本,不适用于稳定的Rust 1.0 io::Error。嵌套模式匹配的 * 概念 * 仍然适用于其他上下文中。
您可以使用模式匹配的一些更高级的特性来匹配作为模式一部分的种类:

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

第一个变量意味着"一个Err包含一个IoError,其中kindIoErrorKind::EndOfFile,所有其他字段都是你喜欢的"。第二个变量则意味着"任何其他Err,将包含的值绑定到变量名e"。

py49o6xq

py49o6xq4#

我想通了。我改了这行来检查错误类型!希望这对其他人有帮助。

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

3xiyfsfu5#

下面是匹配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;
    }
}

相关问题