[英]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!
工作:
由於您正在實現PartialEq for Data,因此RHS為T
且LHS為Data
,因此您只能使用Data::from(5) == 5
而不是5 == Data::from(5)
。
如果要使用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.