首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有实现`dyn::error::== dyn::error::error‘

没有实现`dyn::error::== dyn::error::error‘
EN

Stack Overflow用户
提问于 2022-06-15 16:26:23
回答 1查看 153关注 0票数 1

我有一个异步函数,它在完成所有的web解析之后返回一个结构。在运行测试时,我得到了错误:no implementation for `dyn std::error::Error == dyn std::error::Error`。我怎么能解决这个问题,或者我做错了什么?

代码语言:javascript
复制
#[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
        );
    }
}

错误输出:

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-15 16:43:05

此错误来自async fn make_it_work()中的async fn make_it_work()调用。

此断言试图比较两个Result<ParsingResult<'a>, Box<dyn error::Error>>值是否相等。Result只在OkErr变体的类型可以与自身进行相等比较时才实现相等比较。这意味着ParsingResult<'a>必须为自己实现PartialEq (由于您的#[derive]而实现),而Box<dyn error::Error>也必须实现PartialEq --但是Box,像Result一样,只有在它包含的值可以进行相等比较时才能实现相等比较,而且error::Error不需要PartialEq (如果需要,那么error::Error无论如何都不会是对象安全的,因此您就不能使用dyn)。

也就是说,不能测试Err情况是否相等,因此Result的这个特定实例化也不能测试是否相等。编译器并不关心您正在检查一个Ok值,这意味着它永远不需要比较Err变量值,它只看到两个Result被比较为相等,并且找不到一个PartialEq实现。

要解决这个问题,您可以修改断言:

代码语言:javascript
复制
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()方法将Result<V, E>映射为Option<V>,将Ok(v)映射到Some(v),将Err(_)映射到None。这有效地放弃了错误,从而绕过了错误类型具有相等比较实现的需要。

如果您希望保留错误信息,以便在测试失败时显示,请考虑将错误映射到具有相等操作的类型。例如,只需将错误映射到字符串化的调试表示。这将将Err变体转换为String,这显然提供了相等的比较。

代码语言:javascript
复制
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));
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72634784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档