为多个错误处理实现trait

4
这样做可能吗?如果不行,为什么?
use std::error::Error;
use std::io::{self, Read};

fn main() {
    if let Err(e) = foo() {
        println!("Error: {}", e);
    }
}

fn foo() -> Result<(), impl Error> {
    let mut buffer = String::new();
    io::stdin().read_to_string(&mut buffer)?;
    let _: i32 = buffer.parse()?;
    Ok(())
}

我收到了这个错误信息:
error[E0282]: type annotations needed
  --> src/main.rs:10:24
   |
10 | fn foo() -> Result<(), impl Error> {
   |                        ^^^^^^^^^^ cannot infer type for `_`
1个回答

8
这里有两个问题:
  1. impl Traits 在编译时静态地被解析为一个具体类型。在这里,您正在尝试返回实现 Error 的两种不同类型:std::io::Errorstd::num::ParseIntError。由于在编译时必须将 impl Trait 解析为仅一个类型,因此无法完成此操作。

  2. ? 运算符调用 From::from 来在错误类型之间进行转换,这意味着它对目标类型很灵活。在这里,目标类型是impl Trait,因此编译器没有足够的信息来知道应选择哪种确切类型。

出于这些原因,使用 impl Traits 并不是正确的工具。您可以通过以下任一方式解决此问题:
  • 使用 Box<dyn Error> 作为返回类型。这将为Error类型实现From<E>,因此转换将自动执行。但这将需要动态分配。
  • 将新的错误类型作为枚举实现,该枚举可以包含函数返回的任何错误类型,并针对这些类型中的每个类型实现From<ErrType>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接