在 Rust 中什么是展开,它用来做什么?

我有这样的代码,使用 .unwrap():

fn main() {
let paths = std::fs::read_dir("/home/user").unwrap();


for path in paths {
println!("Name: {}", path.unwrap().path().display());


}
}

看过 unwrap的定义之后,

pub fn unwrap(self) -> T {
match self {
Ok(t) => t,
Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", e),
}
}

还有 signature of read_dir

pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir>

Am I correct in understanding that unwrap returns the T type that is passed in Result?

72125 次浏览

在 Rust 中,当您有一个可能返回 T或者失败的操作时,您将拥有一个类型为 Result<T,E>或者 Option<T>的值(如果出现有趣的错误,E将是错误条件)。

如果有的话,函数 unwrap(self) -> T会给你嵌入的 T。如果取而代之的不是 T而是 ENone,那么它就会恐慌。

It is best used when you are positively sure that you don't have an error. If that is not the case usually it is better either pattern-match the error or use the try! ? operator to forward the error.

在您的示例中,对 read_dir()的调用返回一个 io::Result<ReadDir>,因为打开目录可能会失败。迭代打开的目录将返回多个类型为 io::Result<DirEntry>的值,因为读取该目录也可能失败。

对于 try! ?,它是这样的:

fn try_main() -> std::io::Result<()> {
let entries = std::fs::read_dir("/home/user")?;


for entry in entries {
println!("Name: {}", entry?.path().display());


}
Ok(())
}


fn main() {
let res = try_main();


if let Err(e) = res {
println!("Error: {}", e);
}
}

看看如何检查每个错误案例。

(更新为使用 ?而不是 try!()。宏仍然可以工作,但是新代码首选 ?)。

问题是从文件中读取一行会产生一个潜在的错误类型

       Result<String,std::io::Error>

Result是枚举。Result 中有两个潜在值,它们用于错误处理和管理。第一个值是 Err。如果填充了 Err,则调用的函数中存在错误。另一个潜在的选择是 Ok。OK 包含一个值。

enum Result<T, E> {
Ok(T),
Err(E),
}

Enum 是复杂类型,而不是单个值。为了得到我们正在寻找的值,我们使用 unwrap()来展开该值。

这里使用 unwrap()来快速处理错误。它可以用于任何返回 ResultOption的函数(选项也是枚举)。如果函数返回一个 OK (值) ,您将得到该值。如果函数返回一个 Err (错误) ,程序就会恐慌。