rust - 如何生成 Rust Result 的错误导致>?
问题描述
我正在尝试生成函数Result
返回的a reqwest::blocking::get
。它返回 aResult<reqwest::blocking::Response, reqwest::Error>
但调用它的函数返回 a Result<reqwest::blocking::Response, Box<dyn std::error::Error>
。
- 为什么我的第一次尝试编译失败?
- 进行这种转换的最惯用的方法是什么?
这是第一次尝试:
fn get_example_fails() -> Result<Response, Box<dyn Error>> {
let result = blocking::get("http://example.com");
result.map_err(|error| Box::new(error))
}
它有以下错误,我不知道如何修复,但觉得通过一些小的调整可能会更习惯 - 但我不确定要调整什么:
error[E0308]: mismatched types
--> src/bittrex.rs:143:9
|
141 | fn get_example_fails() -> Result<Response, Box<dyn Error>> {
| -------------------------------- expected `Result<reqwes
t::blocking::Response, Box<(dyn StdError + 'static)>>` because of return type
142 | let result = blocking::get("http://example.com");
143 | result.map_err(|error| Box::new(error))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn StdError`,
found struct `reqwest::Error`
|
= note: expected enum `Result<_, Box<(dyn StdError + 'static)>>`
found enum `Result<_, Box<reqwest::Error>>`
这种尝试编译但似乎很冗长:
fn get_example_works() -> Result<Response, Box<dyn Error>> {
let result = blocking::get("http://example.com");
match result {
Ok(resp) => Ok(resp),
Err(error) => Err(Box::new(error)),
}
}
解决方案
这是因为编译器在这里过于热心。请注意,就像编译器报告的那样,Box::new(error)
只需放入error
a Box
,您就会得到一个强类型的 。Box<reqwest:Error>
但是你想要的是一个 trait 对象dyn Error
,它Box<reqwest:Error>
可能是,但编译器并没有做出那种削弱类型的假设。修复是手动明确的:
fn get_example_fails() -> Result<Response, Box<dyn Error>> {
let result = blocking::get("http://example.com");
result.map_err(|error| Box::new(error) as Box<dyn Error>)
}
注意 extra as Box<dyn Error>
,它使编译器清楚地知道该值应该被向下转换,并且它是一个具体的事实reqwest::Error
应该Box
被删除。
第二个示例编译良好的原因是类型推断。在第一个示例中,从函数返回的类型将是从返回的类型.map_err()
,即 a Result<Response, Box<reqwest::Error>>
- 就是这样。类型不匹配,因此您收到错误消息。在第二个示例中,match
构造一个全新的Result
,Rust 必须为此推断T
and E
;所以类型推断开始了。在第二种情况下,由于函数返回值的推断是成功的Box<dyn Error>
。但是使用map_err()
,类型推断不能“查看” map_err()
-body 并削弱它的返回类型;已经太晚了,类型是固定的。这就是为什么您必须按照上面的建议手动执行此操作。
推荐阅读
- android - Kotlin Flow - 可空值
- llvm - LLVM IR如何将结构传递给函数
- python - “ImmutableDenseNDimArray”对象没有属性“as_independent”
- r - 同时选择和 pivot_wider
- html - 如何创建自定义字体以使用 font awesome 的星号图标
- mysql - mysqlclient.lib 8.0.21 导致内存泄漏
- java - Firebase 动态链接在安装后首次启动时不会调用动态链接
- python - 如何在python中打印循环中分配的值?
- express - 如果方法是 GET 且受支持但未传递参数,如何在 nextjs(服务器)中抛出错误?
- azure - 如何在 Microsoft Graph Mail API 上为 $filter 使用“in”运算符?