Box <dyn Trait>传播问号错误

时间:2019-07-22 05:41:26

标签: rust traits

我想要一个main函数,其代码可以生成/传播一种以上的错误,如下所示:

fn main() -> Result<(), Box<dyn std::fmt::Debug>> // trait common to all my error types
{
    let contents = match std::fs::read_to_string("my.txt") // std::io::Error
    {
        Ok(s) => s,
        Err(e) => return Err(Box::new(e)),
    };
    let number = match contents.parse::<i32>() // std::num::ParseIntError
    {
        Ok(n) => n,
        Err(e) => return Err(Box::new(e)),
    };
    println!("Number is {}!", number);
    return Ok(());
}

这可行,但相当冗长,据我了解,这正是?运算符应该提供的帮助。而且,如果我将Box::new结构移到map_err中,那么剩下的代码实际上只是样板代码:

fn main() -> Result<(), Box<dyn std::fmt::Debug>>
{
    let contents = match std::fs::read_to_string("my.txt").map_err(|e| Box::new(e))
    {
        Ok(s) => s,
        Err(e) => return Err(e),
    };
    let number = match contents.parse::<i32>().map_err(|e| Box::new(e))
    {
        Ok(n) => n,
        Err(e) => return Err(e),
    };
    println!("Number is {}!", number);
    return Ok(());
}

但是当我尝试将其更改为使用?运算符时,就像这样:

fn main() -> Result<(), Box<dyn std::fmt::Debug>>
{
    let contents = std::fs::read_to_string("my.txt").map_err(|e| Box::new(e))?;
    let number = contents.parse::<i32>().map_err(|e| Box::new(e))?;
    println!("Number is {}!", number);
    return Ok(());
}

我得到了两个甚至更多的详细编译器错误:

error[E0277]: `?` couldn't convert the error to `std::boxed::Box<dyn std::fmt::Debug>`
 --> test.rs:3:78
  |
3 |     let contents = std::fs::read_to_string("my.txt").map_err(|e| Box::new(e))?;
  |                                                                              ^ the trait `std::convert::From<std::boxed::Box<std::io::Error>>` is not implemented for `std::boxed::Box<dyn std::fmt::Debug>`
  |
  = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
  = help: the following implementations were found:
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<E>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<&str>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::borrow::Cow<'a, str>>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::string::String>>
          and 16 others
  = note: required by `std::convert::From::from`

error[E0277]: `?` couldn't convert the error to `std::boxed::Box<dyn std::fmt::Debug>`
 --> test.rs:4:66
  |
4 |     let number = contents.parse::<i32>().map_err(|e| Box::new(e))?;
  |                                                                  ^ the trait `std::convert::From<std::boxed::Box<std::num::ParseIntError>>` is not implemented for `std::boxed::Box<dyn std::fmt::Debug>`
  |
  = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
  = help: the following implementations were found:
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<E>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<&str>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::borrow::Cow<'a, str>>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::string::String>>
          and 16 others
  = note: required by `std::convert::From::from`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.

为什么这样不起作用? rustc --explain E0277只告诉我我使用某种类型的特征来实现上述特征,但据我所知,两种错误类型 do 都实现了std::fmt::Debug

0 个答案:

没有答案