繁体   English   中英

`dyn std::error::Error == 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仅在OkErr变体的类型可以与它们自身进行相等比较时才实现相等比较。 这意味着ParsingResult<'a>必须为自己实现PartialEq (它确实是由于你的#[derive] )并且Box<dyn error::Error>也必须实现PartialEq - 但是BoxResult一样,仅在以下情况下实现相等比较它包含的值可以比较是否相等,并且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(_)映射到NoneResult<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM