簡體   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