rust 处理serde错误和其他错误类型?

daupos2t  于 2022-12-29  发布在  其他
关注(0)|答案(1)|浏览(220)

我有下面的export_directory函数。

// For handling multiple error type
type BoxResult<T> = Result<T, Box<std::error::Error>>;

fn export_directory(dir: &Directory, export_path: &str) -> BoxResult<String> {
  let mut file = OpenOptions::new().write(true).truncate(true).create(true).open(export_path)?;
  serde_json::to_string(dir).or_else(|err| Err(Box::new(err)))
}

fn main() {
  let mut dir = Directory::new();
  export_directory(&dir, "export_path.json");
}

当我编译代码的时候,它给了我

error[E0308]: mismatched types
  --> src/main.rs:98:3
   |
96 | fn export_directory(dir: &Directory, export_path: &str) -> BoxResult<String> {
   |                                                            ----------------- expected `std::result::Result<std::string::String, std::boxed::Box<(dyn std::error::Error + 'static)>>` because of return type
97 |   let mut file = OpenOptions::new().write(true).truncate(true).create(true).open(export_path)?;
98 |   serde_json::to_string(dir).or_else(|err| Err(Box::new(err)))
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait std::error::Error, found struct `serde_json::error::Error`
   |
   = note: expected type `std::result::Result<_, std::boxed::Box<(dyn std::error::Error + 'static)>>`
              found type `std::result::Result<_, std::boxed::Box<serde_json::error::Error>>`

但是当引用serde documentation时,serde_json::error::Error已经实现了Error trait,这里出了什么问题?

t3psigkw

t3psigkw1#

rustc无法自动推断闭包中的BoxBox<dyn std::error::Error>还是Box<serde_json::Error>,你必须告诉编译器你实际上是在创建一个boxed trait对象而不是boxed struct。
另一方面,不能直接调用Box::<std::error::Error>::new,因为Error不扩展std::marker::Sized
但是,serde_json::Error确实可以装箱到装箱的std::error::Error中,因此可以使用as运算符强制执行此转换:

result.map_err(|err| Box::new(err) as Box<dyn std::error::Error>)

Working example on Rust Playground

相关问题