您可以返回与任何可能的错误类型一起使用的结果吗? [英] Can you return a Result that works with any possible error type?

查看:63
本文介绍了您可以返回与任何可能的错误类型一起使用的结果吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用每个都有自己的错误类型的多个库。我不太在乎每个特定包装箱的错误类型,我想使用惯用法来使用那些返回 Result的包装箱的方法类型。

I want to use multiple libraries that each have their own error types. I don't really care about each specific crate's error type and I want to use the ? idiom to use the methods of those crates that return a Result type.

我也不想解包这些值,如果遇到错误,这将引起恐慌。我可能只想使用将不同的错误传播到顶部,并且可能选择处理这些错误,或者如果愿意,可以忽略它们。

I don't want to unwrap the values either, that would cause a panic if it hits an error. I might just want to propagate the different errors using ? to the top and perhaps choose to deal with them or ignore them if I want.

我无法使用 std :: result :: Result< T,E> 做到这一点,因为我不知道返回的错误类型(例如我说过,每个板条箱都可能返回自己的错误。)

I cannot do that with a std::result::Result<T, E> because I don't know the type of error returned (like I said, each crate could return its own errors).

我知道Rust中没有面向对象多态性,但有特征对象。由于无法在编译时知道特征对象的大小,因此我们必须将它们隐藏在诸如& Box< __> code>。

I am aware that in Rust there is no "object-oriented" polymorphism, but there are trait objects. Since a trait object's size cannot be known at compile time, we must hide them behind some kind of pointer like & or Box<_>.

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

The base trait implemented by errors seems to be std::error::Error.

我见过的一件事是 fn foo()->。结果< Blah,Box< dyn Error>> 策略,该策略利用了特征对象的概念。

One thing I've seen is the fn foo() -> Result<Blah, Box<dyn Error>> strategy, which utilizes the concept of trait objects.

此策略的问题不存在板条箱中的一个返回框错误,导致编译器抱怨相同。

The problem with this strategy is none of the crates return a boxed error, which leads to the compiler complaining about the same.

一个用例示例:

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)
}

游乐场

有解决此问题的简便方法吗?我可以轻松地提取所有不同的错误并返回 Result 以便使用吗?习惯用法吗?

Is there an easy way around this problem? Can I easily abstract away all the different errors and return a Result so I can use the ? idiom?

推荐答案


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

Can you return a Result that works with any possible error type?

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

No, you cannot. On the surface, this cannot make sense. Generic types are chosen by the caller of the function, so how would a function create an error that was chosen by someone else, without being told how to construct it?

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

That said, your problem is easily solved. You said:


所以我可以使用吗?惯用语

如果您始终如一地执行,则您的程序会编译:

If you do that consistently, your program compiles:

let s = String::from_utf8(res)?;
Ok(s)

您还可以直接转换错误类型:

You could also convert the error type directly:

String::from_utf8(res).map_err(Into::into)




没有一个板条箱返回装箱错误,这导致编译器抱怨相同的错误

none of the crates return a boxed error, which leads to the compiler complaining about the same

在其他 5 个使用吗?的情况下不适用,所以目前尚不清楚

It does not for the 5 other cases where you've used ?, so it's unclear why you make this statement.

具体来说, Box< dyn错误> 可以可以通过实现 Error 的任何类型创建

Specifically, Box<dyn Error> can be created from any type that implements Error:

impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
    fn from(err: E) -> Box<dyn Error + 'a> {
        Box::new(err)
    }
}

运算符在幕后为您调用 From :: from

The ? operator calls From::from for you under the hood.

另请参见:

  • What is this question mark operator about?
  • How to manually return a Result<(), Box<dyn Error>>?
  • Rust proper error handling (auto convert from one error type to another with question mark)

这篇关于您可以返回与任何可能的错误类型一起使用的结果吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆