我想要一个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