Is there some way to implement a trait on multiple

2019-07-20 04:40发布

问题:

Why doesn't this work:

trait Update {
    fn update(&mut self);
}

trait A {}
trait B {}

impl<T: A> Update for T {
    fn update(&mut self) {
        println!("A")
    }
}

impl<U: B> Update for U {
    fn update(&mut self) {
        println!("B")
    }
}
error[E0119]: conflicting implementations of trait `Update`:
  --> src/main.rs:14:1
   |
8  | impl<T: A> Update for T {
   | ----------------------- first implementation here
...
14 | impl<U: B> Update for U {
   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

I would assume it is checked later if types overlap.

回答1:

What would you expect the output of this program to be?

struct AAndB {}
impl A for AAndB {}
impl B for AAndB {}

let a_and_b = AAndB {};
a_and_b.update();

There is an unstable compiler feature, specialization, which you can enable in nightly builds, which lets you have overlapping instances, and the most "specialized" is used.

But, even with specialization enabled, your example won't work because A and B are completely equivalent so you could never unambiguously pick an instance.

As soon as there is an obviously "more specialized" instance, it will compile and work as expected - provided you are using a nightly build of Rust with specialization enabled. For example, if one of the traits is bounded by the other, then it is more specialized, so this would work:

#![feature(specialization)]

trait Update {
    fn update(&mut self);
}

trait A {}
trait B: A {}

impl<T: A> Update for T {
    default fn update(&mut self) {
        println!("A")
    }
}

impl<U: B> Update for U {
    fn update(&mut self) {
        println!("B")
    }
}

Specifying the implementation method as default allows another more specific implementation to define its own version of the method.