diff --git a/src/error-handling/anyhow.md b/src/error-handling/anyhow.md index ba5d57a..ca7e7d9 100644 --- a/src/error-handling/anyhow.md +++ b/src/error-handling/anyhow.md @@ -1 +1,36 @@ # anyhow + +上一节讲到的 `thiserror` 库, 比较适合应用在自定义的库中; 这节介绍的 `anyhow` 更适合用在最终发布的可执行程序里. + +## Error + +这个库里提供的 `anyhow::Error` trait, 用于简化动态的错误类型, 它类似于 `Box`, +但有以下的区别: + +- `anyhow::Error` 要求错误实现了 `Send + Sync + 'static` +- `anyhow::Error` 要求实现代码回溯(backtrace) +- `anyhow::Error`表示一个瘦指针(narrow pointer), 只需要占用一个 word size; + 而胖指针(fat pointer) 需要占两个 word size + +## Result + +`anyhow::Result` 类似于标准库里定义的 `std::io::Result`. +要注意的是, `Result?` 将错误类型转换为 `anyhow::Error`时, 会丢去一部分类型信息, +需要用 `downcast()` 等方法才能访问被包装在内部的错误内型; +如果需要对不同的错误类型单独处理时, 应该考虑用 `thiserror` 库. + +`anyhow::Result::context()` 方法, 可以给错误对象添加上下文描述信息. +比如文件无法访问时, 可以打印出文件路径: + +```rust, not_run +let content = fs::read(path) + .with_context(|| format!("Failed to read instrs from {}", path.display()))?; +``` + +## Chain + +`anyhow::Chain` 用于在一个位置处理所有的错误, 它本身实现了迭代器 Iterator 接口. + +## 参考 + +- [anyhow document](https://docs.rs/anyhow/latest/anyhow/) \ No newline at end of file diff --git a/src/error-handling/thiserror.md b/src/error-handling/thiserror.md index ff693cc..43b07f9 100644 --- a/src/error-handling/thiserror.md +++ b/src/error-handling/thiserror.md @@ -23,7 +23,8 @@ pub enum DataStoreError { } ``` -它会根据宏定义, 自动为结构体实现 `Display` trait. +它会根据宏定义, 自动为结构体实现 `Display` trait, 它们跟让文介绍的手写的错误类型是兼容的, 可以 +随时进行互相的替换. ## 参考