繁体   English   中英

为引用和非引用类型实现特征会导致实现冲突

[英]Implementing a trait for reference and non reference types causes conflicting implementations

我正在尝试创建一个特征并为所有非引用类型提供一个实现,并为所有引用类型提供另一个实现。

这无法编译:

trait Foo {}
impl<T> Foo for T {}
impl<'a, T> Foo for &'a mut T {}

这失败了,错误

error[E0119]: conflicting implementations of trait `Foo` for type `&mut _`:
 --> src/main.rs:3:1
  |
2 | impl<T> Foo for T {}
  | -------------------- first implementation here
3 | impl<'a, T> Foo for &'a mut T {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&mut _`

奇怪的是,这有效:

trait Bar {}

impl<T> Bar for T
where
    T: Clone,
{}

impl<'a, T> Bar for &'a mut T
where
    T: Clone + 'static,
{}

为什么具有Clone约束的版本有效,如何在没有它的情况下使其工作?

正如您所了解的那样,通用T可以是任何¹,因此只要第一个impl中的T&'a mut UFoo就会重叠(冲突),因为第二个impl也涵盖了这种情况(当TU )。

Clone版本的工作原理只是因为&mut引用永远不会实现Clone ,因此T where T: Clone之间没有重叠, T where T: Clone&'a mut T T.2。如果你试图为不可变( & )引用实现Bar ,你将再次发生冲突,因为不可变引用确实实现了Clone

如果没有它,我可以让它工作吗?

如果用“it”表示引用类型的一个实现,而另一个用于非引用类型的实现,则在Rust中不可能出于同样的原因,你不能为struct s实现一种特性,而另一种方式用于enum :根本没有办法表达它(在当前的Rust中)。

一个可能适合您的常见模式是为您需要的任何非引用类型单独实现您的特征,然后添加“覆盖impl”,其涵盖对已经实现特征的类型的任何引用,例如:

impl Foo for u32 { ... }
impl Foo for i32 { ... }
impl<'a, T> Foo for &'a T where T: Foo + 'a { ... }
impl<'a, T> Foo for &'a mut T where T: Foo + 'a { ... }

¹嗯,任何Sized东西,至少。 你必须添加?Sized如果这不是你想要的。

² where T: Clone + 'static子句无关紧要,因为&'a mut T将永远无法Clone无论T本身是否存在。

Clone版本工作的原因是因为实现特征的类型不再在实现上发生冲突。

以第一个示例为例,添加默认实现。

trait Foo {
    fn hi(&self){
        println!("Hi");
    }
}

然后我们impl<T> Foo for T {}使用impl<T> Foo for T {} Foo为所有类型T实现Foo ,这实际上足以让我们使用对类型的引用并使用Foo特征。 例如:

fn say_hi<'a>(b: &'a mut Foo){
    b.hi();
}

fn main(){
    let mut five = 5;

    five.hi(); // integer using Foo
    say_hi(&mut five); // &'a mut Foo
}

为了回答你问题的第二部分,你不需要第二个实现impl<'a,T> Foo for &'a mut T {}因为impl<T> Foo for T {} impl<'a,T> Foo for &'a mut T {} impl<T> Foo for T {}足以给你什么你在找。

现在我们已经看到第一个示例在没有第二个实现的情况下工作,它开始有意义,使用Clone的示例有效,因为您正在实现类型T的子集,它们是Clone和不同的类型子集&'a mut T Clone+static

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM