锈-如何精确,优雅地处理错误?

时间:2019-08-10 04:21:39

标签: error-handling rust

很抱歉为这个标题命名不明确,但我无法提出更好的标题。

read_dir()中定义的std::fs方法返回io::Result<DirEntry>的实例,该实例是Result<DirEntry, io::Error>的别名。当调用方在文件系统上不存在时,它将返回错误。

现在我的代码是

dir_a.read_dir();
dir_b.read_dir();
dir_c.read_dir();

并且dir_adir_bdir_c可能都不存在。因此,这三个语句可能返回相同的io::Error,但是对于我的程序,dir_adir_bdir_c具有不同的含义,在这里我要为每个错误处理错误分别。

所以我将自己的枚举MyError定义为

enum MyError {
    Dir_a_not_exist,
    Dir_b_not_exist,
    Dir_c_not_exist,
}

如何将相同的io::Error转换为不同的三个MyError

我的丑陋方式是

match dir_a.read_dir() {
    Ok => match dir_b.read_dir() {
              Ok => match dir_c.read_dir() {
                        Ok => { /* do something */ },
                        Err => return MyError::Dir_c_not_exist,
                    },
              Err => return MyError::Dir_b_not_exist,
          },
    Err => return MyError::Dir_a_not_exist,
};

有什么优雅的方式可以解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

Result具有一个名为or的函数,如果可以的话,您可以转发结果,如果出现错误,则可以将其转换。这样,您可以执行以下操作:

fn foo(dir_a: &Path, dir_b: &Path, dir_c: &Path) -> Result<(), MyError> {
    dir_a.read_dir().or(Err(MyError::DirAnotExist))?;
    dir_b.read_dir().or(Err(MyError::DirBnotExist))?;
    dir_c.read_dir().or(Err(MyError::DirCnotExist))?;

    /* do something */

    Ok(())
}