【问题标题】:What is unwrap in Rust, and what is it used for?Rust 中的 unwrap 是什么,它的用途是什么?
【发布时间】:2016-07-21 14:18:30
【问题描述】:

我有这段代码使用.unwrap():

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

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

    }
}

看了definition of 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>

我是否正确理解 unwrap 返回在 Result 中传递的 T 类型?

【问题讨论】:

  • @Shepmaster 感谢非常有用的链接,对不起我的英语
  • 英语不好没必要道歉;只要有人能够理解这个问题,我们就可以清理它。请务必搜索以前的问题并解释为什么您的问题与它们不重复。
  • @Shepmaster 如果我见过他,第一个链接,但我发现它是一件事和另一件事之间的区别,并且谈论“选项”,我不确定我们是否谈论相同的“结果”现在我理解得更好了,感谢回复,现在可以以任何方式理解为重复,在我以前从未见过的第二个链接上,感谢一切

标签: rust


【解决方案1】:

在 Rust 中,当您的操作可能返回 T 或失败时,您将获得 Result&lt;T,E&gt;Option&lt;T&gt; 类型的值(E 将是一个有趣的错误条件错误)。

函数unwrap(self) -&gt; T 将为您提供嵌入的T(如果有的话)。如果不是T,而是ENone,那么它会恐慌。

最好在您确定没有错误时使用。如果不是这种情况,通常最好对错误进行模式匹配或使用 try! ? 运算符转发错误。

在您的示例中,对read_dir() 的调用返回io::Result&lt;ReadDir&gt;,因为打开目录可能会失败。并且迭代打开的目录会返回多个io::Result&lt;DirEntry&gt; 类型的值,因为读取目录也可能会失败。

使用 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!()。宏仍然有效,但新代码首选?

【讨论】:

  • 感谢@rodrigo 的精彩解释。 interesting error 是什么意思 - 已知或可捕获(如其他语言)?
  • @RajeevRanjan:以打开文件为例:它可能会失败,因为您缺少权限,或者因为文件不存在,或者因为您请求写权限并且它是只读的,或者因为文件系统已损坏,或者它是一个远程文件系统并且网络已关闭......这很有趣!你可能想知道它为什么会失败。 OTOH,在哈希表或字典中查找值,如果不存在,就是这样,这不是一个有趣的错误,也没有额外的错误代码或数据可获取。第一种情况是Result&lt;T, E&gt;,第二种情况是Option&lt;T&gt;
  • Rust 应该寻找这种垃圾的替代品.. 有时我看到一些像 a.unwrap().b.unwrap().c 这样的代码,它一团糟。
  • @SerakShiferaw:嗯,unwrap() 的替代方法是使用? 运算符。错误和失败只是编程生命中的一个事实。其他语言要么使用异常、错误代码,要么直接忽略任何错误……它们各有利弊。
  • @Ben: 太多的unwrap() 是编程草率的标志,如果是原型或乱跑的程序都可以。一些不能(或不应该)失败的unwrap() 是可以的,例如NonZeroU32::new(1).unwrap():如果你的假设是错误的并且失败了,程序就会出现恐慌,一种错误检查中止,这是正确的结果。跨度>
猜你喜欢
  • 2010-09-27
  • 2011-12-17
  • 2010-11-21
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
相关资源
最近更新 更多