如何在Rust中进行错误处理以及常见的陷阱? [英] How to do error handling in Rust and what are the common pitfalls?

查看:171
本文介绍了如何在Rust中进行错误处理以及常见的陷阱?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到Rust没有例外。如何在Rust中进行错误处理以及常见的陷阱?有什么方法可以通过加注,接球,再加注和其他方式控制流量?我发现不一致的信息。

I noticed that Rust does not have exceptions. How to do error handling in Rust and what are the common pitfalls? Are there ways to control flow with raise, catch, reraise and other stuff? I found inconsistent information on this.

推荐答案

Rust通常以两种方式解决错误:

Rust generally solves errors in two ways:


  • 不可恢复的错误。一旦您恐慌!,就是这样。您的程序或线程中止是因为它遇到无法解决的问题,并且其不变量已被违反。例如。如果您在应该为UTF-8字符串的字符串中发现无效序列。

  • Unrecoverable errors. Once you panic!, that's it. Your program or thread aborts because it encounters something it can't solve and its invariants have been violated. E.g. if you find invalid sequences in what should be a UTF-8 string.

可恢复的错误。在某些文档中也称为失败。您不必惊慌,而是发出 Option< T> Result< T,E> 。在这些情况下,您可以选择有效值分别为 Some(T) / Ok(T)无效值 / 错误(E)。通常 None 用作 null 的替换,表明该值缺失。

Recoverable errors. Also called failures in some documentation. Instead of panicking, you emit a Option<T> or Result<T, E>. In these cases, you have a choice between a valid value Some(T)/Ok(T) respectively or an invalid value None/Error(E). Generally None serves as a null replacement, showing that the value is missing.

现在是最困难的部分。

Now comes the hard part. Application.

有时处理 Option 是脖子上的疼痛,几乎可以保证您会得到一个价值,而不是一个错误。

Sometimes dealing with an Option is a pain in the neck, and you are almost guaranteed to get a value and not an error.

在这种情况下,使用 unwrap 完全可以。 解包变成某些(e)好(e)放入 e ,否则会慌乱。展开是将您的可恢复错误变为不可恢复的工具。

In those cases it's perfectly fine to use unwrap. unwrap turns Some(e) and Ok(e) into e, otherwise it panics. Unwrap is a tool to turn your recoverable errors into unrecoverable.

if x.is_some() {
    y = x.unwrap(); // perfectly safe, you just checked x is Some
}

在<$ c内$ c> if -block完全可以解开,因为它永远不会死机,因为我们已经检查了它是 Some x.is_some()

Inside the if-block it's perfectly fine to unwrap since it should never panic because we've already checked that it is Some with x.is_some().

如果您正在编写库,请使用 unwrap ,因为当发生紧急情况时,用户无法处理该错误。此外,将来的更新可能会更改不变量。想象一下,如果上面的示例具有 if x.is_some()|| always_return_true()。不变式将发生变化,解包可能会出现紧急情况。

If you're writing a library, using unwrap is discouraged because when it panics the user cannot handle the error. Additionally, a future update may change the invariant. Imagine if the example above had if x.is_some() || always_return_true(). The invariant would changed, and unwrap could panic.

是什么?运算符还是 try!宏?简短的解释是,它要么返回 Ok()内的值,要么过早返回错误。

What's the ? operator or the try! macro? A short explanation is that it either returns the value inside an Ok() or prematurely returns error.

这里是运算符或宏扩展为的简化定义:

Here is a simplified definition of what the operator or macro expand to:

macro_rules! try {
    ($e:expr) => (match $e {
        Ok(val) => val,
        Err(err) => return Err(err),
    });
}

如果您这样使用:

let x = File::create("my_file.txt")?;





let x = try!(File::create("my_file.txt"));

它将转换为以下内容:

let x = match File::create("my_file.txt") {
    Ok(val)  => val,
    Err(err) => return Err(err),
};

缺点是您的函数现在返回 Result

The downside is that your functions now return Result.

Option Result 有一些方便的方法,这些方法可以链接并处理可理解的错误方式。诸如 and_then ,<$ c的方法$ c> or_else ok_or map_err 等。

例如,您可以使用默认值,以防损坏值。

For example, you could have a default value in case your value is botched.

let x: Option<i32> = None;
let guaranteed_value = x.or(Some(3)); //it's Some(3)

或者如果您想打开选项转换为结果

Or if you want to turn your Option into a Result.

let x = Some("foo");
assert_eq!(x.ok_or("No value found"), Ok("foo"));

let x: Option<&str> = None;
assert_eq!(x.ok_or("No value found"), Err("No value found"));






这只是您可以做的一小件事做。有关更多说明,请查看:


This is just a brief skim of things you can do. For more explanation, check out:

  • http://blog.burntsushi.net/rust-error-handling/
  • https://doc.rust-lang.org/book/ch09-00-error-handling.html
  • http://lucumr.pocoo.org/2014/10/16/on-error-handling/

这篇关于如何在Rust中进行错误处理以及常见的陷阱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆