[英]Implement a trait for all types implementing a trait
I have this issue:我有这个问题:
Event
Event
多个结构PartialEq
trait the same wayPartialEq
trait 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!");
}
This fails to compile:这无法编译:
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
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
?或者是否有另一种方法可以通用地实现这个
PartialEq
而不必为NoteOn
输入一次,为Noteff
输入一次?
thank you谢谢你
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.这是我最好的“尝试”,以一种可能的方式做我想做的事,但以不同的方式遵循@trentcl 和@Shepmaster 的评论。
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.我使用@trentctl 提到的 Enum 能够在不同类型之间切换,我将枚举值保留在一个公共结构事件中,以便我可以轻松地包装不同的对象并向事件添加更多代码。 Doing this also helps to make an easy Vec type.
这样做也有助于制作一个简单的 Vec 类型。
Here i imagine that i only need the Enum, and not Event and an attribute with the enum, I am still learning the variant enum usage在这里,我想我只需要枚举,而不需要事件和枚举的属性,我仍在学习变体枚举的用法
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.我也遇到了@trentcl 提到的关于我不拥有 Vec 类型这一事实的问题,所以我将 Vec 包装在一个 struct Sec 中,而不是简单地将类型别名化。 This makes my implementation of PartialEq seperated from the type Vec (if i understand, but im not sure) => the reason i am troubled here is that I thought that using
type A = B;
这使得我的 PartialEq 实现与 Vec 类型分离(如果我理解,但我不确定)=> 我在这里感到困扰的原因是我认为使用
type A = B;
did create a new type, but the documentation does state it s aliasing (which could make send to why im 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确实创建了一个新类型,但文档确实说明了它的别名(这可能会导致为什么我无法为 Vec 实现 PartialEq)尽管最后我想我在这方面也可能是非常错误的,因为我创建了一个仅包装 1 个属性的人工结构似乎也适得其反
=> 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 . => 所以现在总结一下谢谢大家,我会继续努力,看看它如何更有效,但我想我只是在 Rust 的上下文中使用了错误的东西,我不确定这是一个好的回答并希望得到反馈或其他建议。
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d67b7d993fa6b6285962ee58e9b215e5 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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.