假设以下对象:
pub struct MyStruct<T>{
items: Vec<T>
}
pub impl<T> MyStruct<T> {
pub fn new() -> MyStruct {
MyStruct{ items::new(); }
}
pub fn add(&mut self, item: T) where T : Eq {
self.items.push(item);
}
}
pub trait C {}
pub struct Another {
mystruct: MyStruct<Box<C>>
}
pub impl Another {
pub fn exec<C>(&mut self, c: C) where C: Eq + C {
self.mystruct.add(c);
}
}在exec上,我强制要求C也是Eq,但是我收到了以下错误:
error: the trait `core::cmp::Eq` is not implemented for the type `C`我不得不
pub impl<T> MyStruct<T> 而不是
pub impl<T : Eq> MyStruct<T> 因为C是一个特性,所以我不能在使用MyStruct::new时强制使用Eq,所以我在函数上保留了类型保护的检查。这里发生了什么事?
发布于 2015-05-17 23:45:46
让我们看一下Eq的相关定义
pub trait Eq: PartialEq<Self> {
…
}
pub trait PartialEq<Rhs: ?Sized = Self> {
fn eq(&self, other: &Rhs) -> bool;
…
}现在考虑MyStruct<Box<C>>:它希望实现Eq的类型是Box<C>,这是一个盒式特征对象。要实现Eq,Box<C>必须首先实现PartialEq<Box<C>>,如下所示:
impl PartialEq for Box<C> {
fn eq(&self, other: &Box<C>) -> bool;
}
impl Eq for Box<C> { }也就是说,您必须能够将任意Box<C>与任何其他任意Box<C>进行比较。您正在比较的盒装特性对象可以是不同的具体类型。因此,您需要手动编写此实现。在这种情况下,您通常希望该特性包括将对象的形式规范化为具体的可比较类型的某种方式;对于某些类型,这是显而易见的;如果AsRef<T>要添加一个PartialEq实现,则要添加的实现非常明显:
impl<T: PartialEq> PartialEq for AsRef<T> {
fn eq(&self, other: &AsRef<T>) -> bool {
self.as_ref() == other.as_ref()
}
}(还请注意,如果C实现了PartialEq,那么Box<C>就实现了,所以我们正在讨论的这种实现应该放在未装箱的属性对象上,而不是在框状的属性对象上。)
然而,通常情况下,没有一个明显和简单的实现。有几种方法你可以采取:
String,然后再进行比较;C约束为'static类型,并使用一些花哨的Any魔术使其能够使用基类型的PartialEq实现,如果这两个特征对象不是相同的具体类型,则返回false。这是一个非常有用的代码,因此我将给出一些代码:
#使用std::any::{Any,TypeId};使用std::mem;fn main() {} PartialEqFromC { fn eq_c(&self,other:&C) -> bool;} impl PartialEqFromC用于T{ fn eq_c(& self,其他:&C) -> bool { if other.get_type_id() == TypeId::of::() {self ==不安全{ *mem::transmute::<&&C,&&Self>(&其他)}
请注意,此示例依赖于Any.get_type_id的不稳定特性Any.get_type_id,因此仅每晚绑定;可以通过将该定义从Any特性复制到新的C超特性来解决这一问题,并且还可以通过 trait进行简化。https://stackoverflow.com/questions/30290658
复制相似问题