为实现特征的所有类型实现特征 [英] Implement a trait for all types implementing a trait

查看:48
本文介绍了为实现特征的所有类型实现特征的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个问题:

  • 实现特征 Event
  • 的多个结构
  • 所有人都可以以相同的方式实现 PartialEq 特性

我考虑写这篇(简短版)

I considered writing this (short version)

type Data = Vec<u8>;

trait Event {
    fn data(&self) -> &Data;
}

struct NoteOn {
    data: Data,
}
struct NoteOff {
    data: Data,
}
impl Event for NoteOn {
    fn data(&self) -> &Data {
        &self.data
    }
}
impl Event for NoteOff {
    fn data(&self) -> &Data {
        &self.data
    }
}
impl<T: Event> PartialEq for T {
    fn eq(&self, b: &T) -> bool {
        self.data() == b.data()
    }
}

fn main() {
    println!("Hello, world!");
}

操场

无法编译:

error[E0119]: conflicting implementations of trait `std::cmp::PartialEq<&_>` for type `&_`:
  --> src/main.rs:23:1
   |
23 | impl<T: Event> PartialEq for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<A, B> std::cmp::PartialEq<&B> for &A
             where A: std::cmp::PartialEq<B>, A: ?Sized, B: ?Sized;
   = note: downstream crates may implement trait `Event` for type `&_`

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
  --> src/main.rs:23:1
   |
23 | impl<T: Event> PartialEq for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
   |
   = note: only traits defined in the current crate can be implemented for a type parameter

这是怎么了?还是有另一种方法可以通用地实现此 PartialEq ,而不必为 NoteOn 输入一次,而为 Noteff 输入一次?

What is wrong here? Or is there another way to implement generically this PartialEq without having to type it once for NoteOn and once for Noteff?

谢谢

推荐答案

这是我最好的尝试",它以一种可能的方式来完成我想要的事情,但遵循@trentcl和@Shepmaster的说明.

Here is my best "attempt" at a possible way to do what i wanted, but in a different way following the remarks from @trentcl and @Shepmaster.

我使用了@trentctl提到的枚举,以便能够在不同类型之间进行切换,我将枚举值保留在通用的struct Event中,以便可以轻松包装不同的对象并向Event添加更多代码.这样做还有助于简化Vec类型.

I used an Enum as mentioned by @trentctl to be able to switch between the different types, I keep the enum value within a common struct Event so I can easily wrap the different objects and add more code to the Event. Doing this also helps to make an easy Vec type.

在这里,我想我只需要枚举,而不需要Event和带有枚举的属性,我仍在学习变体枚举用法

我还遇到了@trentcl提到的问题,即我不拥有Vec类型,因此我将Vec封装在struct Sec中,而不是简单地别名.这使我的PartialEq的实现与Vec类型分开(如果我理解,但我不确定)=>我在这里感到困扰的原因是我认为使用 type A = B; did创建了一个新类型,但是文档确实指出了它的别名(这可能导致发送到为什么im无法为Vec实施PartialEq)尽管最后我想我可能对此也很错,因为我创建了一个只包装1个属性的人工结构这一事实似乎也适得其反

I also had issues mentioned by @trentcl about the fact i did not own the Vec type, so i wrapped the Vec in a struct Sec instead of simply aliasing the type. This makes my implementation of PartialEq seperated from the type Vec (if i understand, but i m not sure) => the reason i am troubled here is that I thought that using type A = B;did create a new type, but the documentation does state it s aliasing (which could make send to why i m not able to implement PartialEq for Vec) although in the end I imagine i may be very wrong on that too as the fact i created an artificial struct to just wrap 1 attribute also seems counter productive

=>因此,现在总结一下,谢谢大家,我将继续努力,看看它如何更有效,但是我想我只是在Rust的上下文中使用了错误的内容,不确定这是一个好答案,将不胜感激反馈或其他建议.

=> So to conclude for now thank you everyone, I will keep working on this to see how it could be more efficient, but I guess I was simply using the wrong stuff for the context of Rust, I am not sure this is a good answer and would appreciate feedbacks or other suggestions.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d67b7d993fa6b6285962ee58e9b215e5

type Data = Vec<u8>;

#[derive(Debug)]
enum EventImpl{
    NoteOn(u8),
    NoteOff(u8)
}
#[derive(Debug)]
struct Event{
    data:Data,
    i:EventImpl
}

impl Event{
    fn new(data:Data)->Self{
        Event{
            i: match data[0]{
                0 => EventImpl::NoteOn(data[1]),
                1 => EventImpl::NoteOff(data[1]),
                _ => panic!("unk")
            },
            data:data
        }
    }

    fn data(&self)->&Data{
        &self.data
    }
}
#[derive(Debug)]
struct Seq{
    pub things:Vec<Event>
}

impl PartialEq for Seq{
    fn eq(&self,o:&Self)->bool{
    // i have to learn the iterator implementation    
        let mut r=o.things.len()==self.things.len();
        if ! r{
            return false;
        }
        for i in 0..o.things.len() {
            r = r && o.things[i]==self.things[i];
        }
        r
    }
}
impl PartialEq for Event{
    fn eq(&self,o:&Self)->bool{
    // i have to learn the iterator implementation    
        std::mem::discriminant(&self.i) == std::mem::discriminant(&o.i) && o.data()==self.data()
    }
}


fn main() {
    let mut s:Seq=Seq{things:vec![Event::new(vec![1,2,3])]};
    s.things.push(Event::new(vec![0,1,2]));
    let s2:Seq=Seq{things:vec![Event::new(vec![1,2,3]),Event::new(vec![0,1,2])]};

    println!("Hello, world! {:?} {:?}",s, s.things[1].data());
    println!("S1 == S2 ? {}",s==s2);
}

这篇关于为实现特征的所有类型实现特征的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆