[英]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.