我正在尝试在我创建的struct和我的struct实现PartialEq
trait的其他类型之间实现From
。真正的代码更复杂,并为其他类型实现From
,但这是核心问题的精简版。
我希望能够做到:
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 {
|> ^
现在我迷失了,因为它暗示我完全按照我所做的去做而拒绝......:/
答案 0 :(得分:7)
编译器是对的:添加where Data: From<&T>
是正确的事情。但正如您已经注意到的那样,在这种情况下需要使用生命周期说明符。但我们如何宣布?
我们想对编译器说些什么:
实施
Data
应为{strong>任何生命周期From<&'a T>
'a
我们无法在impl
块上声明生命周期,因为这表达了不同的内容。我们需要使用“higher-ranked lifetime bounds”,如下所示:
where Data: for<'a> From<&'a T>
// ^^^^^^^
这可以解决您的主要问题。
有两个小的,无关的,额外的问题:
assert_eq!()
中的参数,因为使用PartialEq
的方式:assert_eq!(s, 5)
#[derive(Debug)]
类型Data
您可以找到工作版 here on the playground。
答案 1 :(得分:4)
您需要进行一项微小的修改才能使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
而不是{{1}进行比较}。
如果您想使用5 == Data::from(5)
,则需要实施Debug
。
最终工作代码:
assert_eq!