繁体   English   中英

使用From类型为结构实现PartialEq

[英]Implementing PartialEq for a struct with From types

我试图在我创建的结构和我的结构实现From trait的其他类型之间实现PartialEq 真正的代码更复杂,并实现From for其他类型,但这是核心问题的精简版本。

我希望能够做到:

let s = Data::from(5);
assert_eq!(5, s);

这是基本代码:

struct Data {
    data: i64,
}

impl From<i64> for Data {
    fn from(v: i64) -> Data {
        Data { data: v }
    }
}

impl<'a> From<&'a i64> for Data {
    fn from(v: &'a i64) -> Data {
        Data { data: v.clone() }
    }
}

这是我的第一次尝试:

impl<T> PartialEq<T> for Data
    where T: Into<Data>
{
    fn eq(&self, other: &T) -> bool {
        let o = Data::from(other);
        self.data == o.data
    }
}

但是我收到一个错误:

error: the trait bound `Data: std::convert::From<&T>` is not satisfied [--explain E0277]
  --> <anon>:21:17
   |>
21 |>         let o = Data::from(other);
   |>                 ^^^^^^^^^^
help: consider adding a `where Data: std::convert::From<&T>` bound
note: required by `std::convert::From::from`

所以我改变了绑定到编译器建议的特性,并添加了所有请求的生命周期来修复missing lifetime specifier错误:

impl<'a, T> PartialEq<T> for Data
    where T: 'a, Data: From<&'a T>
{
    fn eq(&self, other: &'a T) -> bool {
        let o = Data::from(other);
        self.data == o.data
    }
}

我得到了

error: method not compatible with trait [--explain E0308]
  --> <anon>:31:5
   |>
31 |>     fn eq(&self, other: &'a T) -> bool {
   |>     ^ lifetime mismatch
note: expected type `fn(&Data, &T) -> bool`
note:    found type `fn(&Data, &'a T) -> bool`
note: the anonymous lifetime #2 defined on the block at 31:39...
  --> <anon>:31:40
   |>
31 |>     fn eq(&self, other: &'a T) -> bool {
   |>                                        ^
note: ...does not necessarily outlive the lifetime 'a as defined on the block at 31:39
  --> <anon>:31:40
   |>
31 |>     fn eq(&self, other: &'a T) -> bool {
   |>                                        ^
help: consider using an explicit lifetime parameter as shown: fn eq(&self, other: &'a T) -> bool
  --> <anon>:31:5
   |>
31 |>     fn eq(&self, other: &'a T) -> bool {
   |>     ^

而现在我迷失了,因为它建议完全按照我的方式行事并拒绝......:/

操场上的代码

编译器是对的:添加where Data: From<&T> 正确的。 但正如您已经注意到的那样,在这种情况下需要使用生命周期说明符。 但我们如何宣布呢?

我们想对编译器说些什么:

Data应该实现From<&'a T>任何生命周期'a

我们不能impl块上声明生命周期,因为它表达了不同的东西。 我们需要使用“更高级别的生命周期界限” ,如下所示:

    where Data: for<'a> From<&'a T>
//              ^^^^^^^

这可以解决您的主要问题。


有两个小的,无关的,额外的问题:

  • 你需要交换assert_eq!()的参数,因为使用了PartialEq的方式: assert_eq!(s, 5)
  • 你需要为你的Data类型#[derive(Debug)]

您可以在操场上找到工作版本

你只需要一个微小的修改来使PartialEq工作:需要Data: From<&'a T>因为你使用Data::from(other)而不是other.into()

impl<T> PartialEq<T> for Data
    where for<'a> Data: From<&'a T>
{
    fn eq(&self, other: &T) -> bool {
        let o = Data::from(other);
        self.data == o.data
    }
}

你还需要两个微小的修改才能生成assert_eq! 工作:

  1. 由于您正在实现PartialEq for Data,因此RHS为T且LHS为Data ,因此您只能使用Data::from(5) == 5而不是5 == Data::from(5)

  2. 如果要使用assert_eq!则需要实现Debug assert_eq!

最终工作代码:

#[derive(Debug)]
struct Data {
    data: i64,
}

impl From<i64> for Data {
    fn from(v: i64) -> Data {
        Data { data: v }
    }
}

impl<'a> From<&'a i64> for Data {
    fn from(v: &'a i64) -> Data {
        Data { data: v.clone() }
    }
}

impl<T> PartialEq<T> for Data
    where for<'a> Data: From<&'a T>
{
    fn eq(&self, other: &T) -> bool {
        let o = Data::from(other);
        self.data == o.data
    }
}

fn main() {
    let s = Data::from(5);
    assert_eq!(s, 5);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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