我注意到 rust 病也没有例外.如何处理 rust 迹中的错误,常见的trap 是什么?有没有办法通过提升、捕获、重新提升和其他方式来控制流量?我发现这方面的信息不一致.

推荐答案

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

  • Unrecoverable errors.一旦你panic!岁了就够了.您的程序或线程中止,因为它遇到了无法解决的问题,并且其不变量已被违反.例如,如果你在UTF-8字符串中发现无效序列.

  • Recoverable errors.在一些文件中也被称为失败.你没有惊慌失措,而是发出Option<T>Result<T, E>的声音.在这些情况下,可以分别 Select 有效值Some(T)/Ok(T)或无效值None/Error(E).通常None用作null替换,表示缺少该值.


现在是最难的部分.应用

打开…的包装

有时候,处理Option是件令人头疼的事,你几乎可以保证得到一个值,而不是一个错误.

在这种情况下,使用unwrap是完全可以的.unwrapSome(e)Ok(e)变成e,否则它就会panic ."展开"是一种将可恢复的错误转化为不可恢复的错误的工具.

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

if号区块内,完全可以打开,因为它永远不会惊慌失措,因为我们已经判断过它是Somex.is_some().

如果你正在写一个库,不鼓励使用unwrap,因为当它惊慌失措时,用户无法处理错误.此外,future 的更新可能会更改不变量.想象一下,如果上面的例子有if x.is_some() || always_return_true().不变量会改变,unwrap可能会panic .

? operator / try! macro

什么是?运算符还是try!宏?一个简短的解释是,它要么返回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.

Select 符

OptionResult有一些方便的方法,允许以可理解的方式链接和处理错误.方法andand_thenoror_elseok_ormap_err等.

例如,如果值出错,可以使用默认值.

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

或者如果你想把你的Option变成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"));

这只是对你能做的事情的简要介绍.有关更多说明,请查看:

Rust相关问答推荐

预期 struct VecDeque Student发现 struct VecDeque Student(Student)

为什么单元类型(空元组)实现了`Extend`trait?

在Rust中赋值变量有运行时开销吗?

在铁 rust 中传递所有权

为昂贵的for循环制作筛子

我如何使用AWS SDK for Rust获取我承担的角色的凭据?

什么时候使用FuturesOrdered?

链表堆栈溢出

borrow 是由于对 `std::sync::Mutex>` 的解引用强制而发生的

为什么实现特征的对象期望比具体对象有更长的生命周期?

将泛型中的 Box 转换为 rust 中的 Box

在Rust中实现Trie数据 struct 的更好方式

Rust 为什么被视为borrow ?

str 和 String 的 Rust 生命周期

在不安全的 Rust 中存储对 struct 内部数据的静态引用是否合法?

如何将 Rust 中的树状 struct 展平为 Vec<&mut ...>?

为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

编写 TOML 文件以反序列化为 struct 中的枚举

如何创建动态创建值并向它们返回borrow 的工厂?

Rust:为什么在 struct 中borrow 引用会borrow 整个 struct?