为什么 Box<dyn std::error::Error> 不捕获 std::string::FromUtf8Error

utp*_*mas 1 rust

我下面有一个简单的程序,它试图打印String从硬编码Vec通过创建的String::from_utf8

我还在这里使用类型别名来减少冗长(例如Result<String, SomeError>vs Result<String>

use std::error;
use std::result;

pub type Error = Box<dyn error::Error>;
pub type Result<T> = result::Result<T, Error>;

fn main() {
    let vec = vec![65; 3];
    let text = String::from_utf8(vec).unwrap();
    println!("result {}", text);
}

fn foo() -> Result<String> {
    let vec = vec![65; 3];
    String::from_utf8(vec)
}
Run Code Online (Sandbox Code Playgroud)

但是该程序无法编译,我收到此错误:

   |
26 | fn foo() -> Result<String> {
   |             -------------- expected `std::result::Result<String, Box<(dyn std::error::Error + 'static)>>` because of return type
27 |     let vec = vec![65; 3];
28 |     String::from_utf8(vec)
   |     ^^^^^^^^^^^^^^^^^^^^^^ expected struct `Box`, found struct `FromUtf8Error`
   |
   = note: expected enum `std::result::Result<_, Box<(dyn std::error::Error + 'static)>>`
              found enum `std::result::Result<_, FromUtf8Error>`
Run Code Online (Sandbox Code Playgroud)

我想知道是否有人对为什么这不起作用有任何见解。我本希望Box<dyn error::Error>捕获所有错误,但它看起来像是FromUtf8Error一个例外(或者也许我只是误解了某些内容)。有没有办法调整自定义Result别名以进行一般捕获FromUtf8Error

mca*_*ton 5

在一种情况下你有FromUtf8Error,在另一种情况下你有Box<Stuff>Stuff完全无关,Rust 从来不会隐式地转换或装箱任何东西。如果要转换错误,请使用?运算符。该运算符尝试转换错误类型,并且可以进行错误装箱:

fn foo() -> Result<String> {
    let vec = vec![65; 3];
    Ok(String::from_utf8(vec)?)
}
Run Code Online (Sandbox Code Playgroud)

  • @utpamas 你_were_返回一个 `Result` 类型,只是不是正确的类型。另一个解决方案是显式映射错误: `String::from_utf8(vec).map_err (Into::into)` ([playground](https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition) =2021&amp;要点=65e77600455e15861a5688e5898e8481)) (2认同)