[英]Rust shorthand for Result<type, Box<dyn std::error::Error>>
[英]no implementation for `dyn std::error::Error == dyn std::error::Error`
我有一个异步函数,它在所有网络解析完成后返回一个结构。 运行测试时出现错误: no implementation for `dyn std::error::Error == dyn std::error::Error`
。 我该如何解决这个问题或我做错了什么?
#[derive(Debug, PartialEq, Eq)]
pub struct ParsingResult<'a> {
title: &'a str,
content: String,
}
impl<'a> ParsingResult<'a> {
pub fn new(title: &'a str, content: String) -> Self {
ParsingResult { title, content }
}
}
pub async fn yahoo_template<'a>(
link_to_the_article: &str,
) -> Result<ParsingResult<'a>, Box<dyn error::Error>> {
let resp = reqwest::get(link_to_the_article).await?.text().await?;
let mut final_res: Vec<String> = Vec::new();
Document::from(resp.as_str())
.find(Name("a"))
.filter_map(|n| n.attr("href"))
.for_each(|x| {
if x.contains("http") || x.contains("https") {
final_res.push(String::from(x));
}
});
// println!("{:?}", final_res);
Ok(ParsingResult::new("Title", String::from("String")))
}
#[cfg(test)]
mod templates_tests {
use super::*;
#[tokio::test]
async fn make_it_work() {
let expected = Ok(ParsingResult::new("Title", String::from("String")));
assert_eq!(
expected,
yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
);
}
}
错误输出:
error[E0277]: can't compare `dyn std::error::Error` with `dyn std::error::Error`
--> src/scraper/scraping_templates.rs:47:3
|
47 | / assert_eq!(
48 | | expected,
49 | | yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
50 | | );
| |_________^ no implementation for `dyn std::error::Error == dyn std::error::Error`
|
= help: the trait `PartialEq` is not implemented for `dyn std::error::Error`
= note: required because of the requirements on the impl of `PartialEq` for `Box<dyn std::error::Error>`
= note: 1 redundant requirement hidden
= note: required because of the requirements on the impl of `PartialEq` for `Result<scraping_templates::ParsingResult<'_>, Box<dyn std::error::Error>>`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
此错误来自async fn make_it_work()
中的assert_eq!()
调用。
此断言尝试比较两个Result<ParsingResult<'a>, Box<dyn error::Error>>
值是否相等。 Result
仅在Ok
和Err
变体的类型可以与它们自身进行相等比较时才实现相等比较。 这意味着ParsingResult<'a>
必须为自己实现PartialEq
(它确实是由于你的#[derive]
)并且Box<dyn error::Error>
也必须实现PartialEq
- 但是Box
和Result
一样,仅在以下情况下实现相等比较它包含的值可以比较是否相等,并且error::Error
不需要PartialEq
(如果确实如此,那么error::Error
无论如何都不是对象安全的,因此您将无法使用dyn
) .
综上所述,不能测试Err
情况是否相等,因此也不能测试Result
的这个特定实例化是否相等。 编译器并不关心您是否检查Ok
值,这意味着它永远不必比较Err
变量值,它只会看到两个Result
被比较是否相等并且找不到PartialEq
实现。
要解决此问题,您可以修改断言:
let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;
assert_eq!(actual.ok(), Some(expected));
.ok()
方法通过将Ok(v)
映射到Some(v)
并将Err(_)
映射到None
将Result<V, E>
转换为Option<V>
。 这有效地丢弃了错误,绕过了错误类型具有相等比较实现的需要。
如果您想保留错误信息以在测试失败时显示,请考虑将错误映射到具有相等操作的类型。 例如,只需将错误映射到字符串化的调试表示。 这会将Err
变体转换为String
,这显然提供了相等比较。
let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;
assert_eq!(actual.map_err(|e| format!("{:?}", e)), Ok(expected));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.