错误处理 – 如何在Rust中进行错误处理以及常见的陷阱是什么?

我注意到Rust没有例外.如何在Rust中进行错误处理以及常见的陷阱是什么?有没有办法通过加注,捕获,重新加注和其他东西来控制流量?我发现这方面的信息不一致.
最佳答案
Rust通常以两种方式解决错误:

>不可恢复的错误.一旦你恐慌!,就是这样.您的程序或线程因为遇到无法解决的问题而中止,并且违反了其不变量.例如.如果在UTF-8字符串中找到无效序列.
>可恢复的错误.在某些文档中也称为失败.您可以发出Option<T>Result<T, E>而不是恐慌.在这些情况下,您可以分别选择有效值Some(T)/ Ok(T)或无效值None / Error(E).通常,None用作null替换,表示缺少该值.

现在来了困难的部分.应用.

有时处理选项是一个痛苦的问题,你几乎可以保证得到一个值,而不是错误.

在这些情况下,使用展开是完全没问题的. unwrap将some(e)和Ok(e)转换为e,否则会引起恐慌.展开是一种将可恢复错误转变为不可恢复的工具.

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

在if-block中,打开它是完全没问题的,因为它应该永远不会出现恐慌,因为我们已经检查过它是x.is_some().

如果您正在编写库,则不鼓励使用unwrap,因为当它发生混乱时,用户无法处理错误.此外,未来的更新可能会更改不变量.想象一下,如果上面的例子有x.is_some()|| always_return_true().不变量会改变,解开可能会引起恐慌.

?运算符/尝试!宏

这是什么?运算符还是试试!宏?一个简短的解释是它要么返回Ok()内部的值,要么过早地返回错误.

以下是运算符或宏扩展到的简化定义:

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.

组合子

OptionResult有一些方便的方法,允许以可理解的方式链接和处理错误.类似于and,and_then,or,or_else,ok_or,map_err等的方法.

例如,如果您的值被拙劣,您可以使用默认值.

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

或者,如果要将选项转换为结果.

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"));

这只是您可以做的事情的简要描述.有关更多说明,请查看:

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

转载注明原文:错误处理 – 如何在Rust中进行错误处理以及常见的陷阱是什么? - 代码日志