如何在Rust中覆盖特定类型的特征实现



在下面的例子中,实现其中任何一个特性都可以。编译器不允许重写特定类型的实现。

还有其他方法可以做到这一点吗?

trait Giver<T,U> {
fn give_first(&self) -> T;
fn give_second(&self) -> U;
}
struct Pair<T,U>(T,U);
impl<T,U> Giver<T,U> for Pair<T,U> where T:Clone, U:Clone {
fn give_first(&self) -> T {
(self.0).clone()
}
fn give_second(&self) -> U {
(self.1).clone()
}
}
//works 
impl Giver<i32, i32> for Pair<f32, f32> {
fn give_first(&self) -> i32 {
1
}
fn give_second(&self) -> i32 {
2
}
}

//error[E0119]: conflicting implementations of trait `Giver<f32, f32>` for type `Pair<f32, f32>`:
impl Giver<f32, f32> for Pair<f32, f32> {
fn give_first(&self) -> f32 {
1.0
}
fn give_second(&self) -> f32 {
2.0
}
}
#![feature(specialization)]
trait Giver<T,U> {
fn give_first(&self) -> T;
fn give_second(&self) -> U;
}
#[derive(Debug)]
struct Pair<T,U>(T,U);
impl<T,U> Giver<T,U> for Pair<T,U> where T:Clone, U:Clone {
default fn give_first(&self) -> T {
(self.0).clone()
}
default fn give_second(&self) -> U {
(self.1).clone()
}
}
impl Giver<i32, i32> for Pair<f32, f32> {
fn give_first(&self) -> i32 {
1
}
fn give_second(&self) -> i32 {
2
}
}

impl Giver<f32, f32> for Pair<f32, f32> {
fn give_first(&self) -> f32 {
3.0
}
fn give_second(&self) -> f32 {
4.0
}
}
fn main() {
{
let p = Pair(0.0, 0.0);
let first: i32 = p.give_first();
let second: i32 = p.give_second();
println!("{}, {}", first, second);  // 1, 2
}
{
let p: Pair<f32, f32> = Pair(0.0, 0.0);
let first: f32 = p.give_first();
let second: f32 = p.give_second();
println!("{}, {}", first, second);  // 3, 4
}
}

如果我们明确指定期望的返回类型,rust-night似乎支持它。我用#![feature(specialization)]试过了。可能会有一个更优雅的解决方案(等待有更多知识的人(。

输出:https://play.rust-lang.org/?version=nightly&mode=调试&edition=2018&gist=d618cd9b534a5a4199a2efdcf607bd

最新更新