Error handling 您能否返回一个适用于任何可能的错误类型的结果?

Error handling 您能否返回一个适用于任何可能的错误类型的结果?,error-handling,rust,Error Handling,Rust,我想使用多个库,每个库都有自己的错误类型。我并不真正关心每个特定板条箱的错误类型,我想使用?习惯用法来使用那些返回结果的板条箱的方法 我也不想打开这些值,如果遇到错误就会引起恐慌。我可能只想使用?将不同的错误传播到顶部,如果需要,可能选择处理它们或忽略它们 我不能用std::result::result这样做,因为我不知道返回的错误类型(就像我说的,每个板条箱都可能返回自己的错误) 我知道Rust中不存在“面向对象”的多态性,但存在特征对象。由于在编译时无法知道trait对象的大小,因此我们必须

我想使用多个库,每个库都有自己的错误类型。我并不真正关心每个特定板条箱的错误类型,我想使用
习惯用法来使用那些返回
结果的板条箱的方法

我也不想打开这些值,如果遇到错误就会引起恐慌。我可能只想使用
将不同的错误传播到顶部,如果需要,可能选择处理它们或忽略它们

我不能用
std::result::result
这样做,因为我不知道返回的错误类型(就像我说的,每个板条箱都可能返回自己的错误)

我知道Rust中不存在“面向对象”的多态性,但存在特征对象。由于在编译时无法知道trait对象的大小,因此我们必须将它们隐藏在某种指针后面,比如
&
Box

错误实现的基本特征似乎是
std::error::error

我看到的一件事是
fn foo()->Result
策略,它利用了trait对象的概念

这种策略的问题是没有一个板条箱返回装箱错误,这会导致编译器抱怨同样的错误

一个示例用例:

use native_tls::TlsConnector; // 0.2.3
use std::io::{Read, Write};
use std::net::TcpStream;

fn main() {
    match do_stuff() {
        Ok(string) => {
            println!("{}", string);
        }
        _ => {
            println!("Failed!");
        }
    }
}

fn do_stuff() -> Result<String, Box<(dyn std::error::Error + 'static)>> {
    let connector = TlsConnector::new()?;

    let stream = TcpStream::connect("jsonplaceholder.typicode.com:443")?;
    let mut stream = connector.connect("jsonplaceholder.typicode.com", stream)?;

    stream.write_all(b"GET /todos/1 HTTP/1.0\r\n\r\n")?;
    let mut res = vec![];
    stream.read_to_end(&mut res)?;
    String::from_utf8(res)
}
使用本机\u tls::TlsConnector;//0.2.3
使用std::io::{Read,Write};
使用std::net::TcpStream;
fn main(){
匹配dou_stuff(){
Ok(字符串)=>{
println!(“{}”,字符串);
}
_ => {
println!(“失败!”);
}
}
}
fn do_stuff()->结果
您能否返回一个适用于任何可能的错误类型的结果

不,你不能。表面上看,这是没有道理的。泛型类型是由函数的调用方选择的,那么函数如何创建由其他人选择的错误,而不被告知如何构造它呢


也就是说,你的问题很容易解决。你说:

所以我可以用
这个成语

如果您始终这样做,您的程序将编译:

let s = String::from_utf8(res)?;
Ok(s)
您还可以直接转换错误类型:

String::from_utf8(res).map_err(Into::into)
没有一个板条箱返回装箱错误,这导致编译器抱怨相同的错误

它不适用于您使用了
5其他情况,因此不清楚您为什么要这样说

具体而言,
Box
可以:

impl From for Box{
框::新建(错误)
}
}
操作员在发动机罩下为您呼叫
From::From

另见:


请粘贴您得到的准确完整的错误-这将有助于我们了解问题所在,以便我们能够提供最好的帮助。有时,试图解释错误消息是很棘手的,实际上,错误消息的另一部分很重要。真的吗-1?我想我很清楚,我发布的游乐场链接只是我描述的困境的一个例子。当一个函数可能返回属于不同板条箱的多个错误
类型时,我如何将它们全部提取出来,以便我可以使用
习惯用法来处理调用函数中的任何(不同)错误类型。
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
    fn from(err: E) -> Box<dyn Error + 'a> {
        Box::new(err)
    }
}