Rust 为引用和非引用类型实现trait会导致实现冲突

Rust 为引用和非引用类型实现trait会导致实现冲突,rust,Rust,我试图创建一个trait,为所有非引用类型提供一个实现,为所有引用类型提供另一个实现 这无法编译: trait Foo {} impl<T> Foo for T {} impl<'a, T> Foo for &'a mut T {} trait Foo{} T{}的impl Foo impl src/main.rs:3:1 | 2 | T{}的impl Foo |---------这里的第一个实现 3 | impl克隆版本之所以有效,是因为实现trait的类型在

我试图创建一个trait,为所有非引用类型提供一个实现,为所有引用类型提供另一个实现

这无法编译:

trait Foo {}
impl<T> Foo for T {}
impl<'a, T> Foo for &'a mut T {}
trait Foo{}
T{}的impl Foo
impl src/main.rs:3:1
|
2 | T{}的impl Foo
|---------这里的第一个实现

3 | impl克隆
版本之所以有效,是因为实现trait的类型在实现上不再冲突

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

trait Foo {
    fn hi(&self){
        println!("Hi");
    }
}
然后我们用
impl Foo for T{}
为所有类型的
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
}

fn说_hi正如您所了解的,一般的
T
可以是任何东西,因此
Foo
在第一个impl中的
T
和'mut U
时都会重叠(冲突),因为第二个impl也涵盖了这种情况(当
T
U

Clone
版本之所以有效,是因为
&mut
引用从未实现
Clone
,因此
T其中T:Clone
&a mut T
之间没有重叠。如果您尝试为不可变(
&
)引用实现
Bar
,您将再次发生冲突,因为不可变引用实现了克隆

[H] 没有它我怎么能让它工作

如果“it”指的是引用类型的一种实现和非引用类型的另一种不同的实现,那么这在Rust中是不可能的,因为同样的原因,您不能以一种方式为
struct
s实现特征,而以另一种方式为
enum
s实现特征:在当前的Rust中根本没有表达它的方法

一种可能适用于您的常见模式是为您需要的任何非引用类型单独实现您的trait,然后添加一个“一揽子impl”,涵盖对已实现trait的类型的任何引用,例如:

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 { ... }
u32{…}的impl Foo i32{…}的impl Foo impl Foo for&'a mut T T其中T:Foo+'a{…}

嗯,至少是
大小的任何东西


²
where T:Clone+'static
子句并不重要,因为无论
T
本身是不是
Clone
impl Foo for T{}
为什么不够?我的意思是,为什么需要专门为
&mut
引用实现它?您是否还需要另一种
&a T
实现?
&mut T T
不是
克隆
&mut T
确实满足T
(因为&mut T T是一种类型,
impl Bar for T
也为每个
&mut T
实现了Bar)。克隆版本不冲突,因为
&mut t
从来都不是
clone
(不能有两个可变引用)。
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 { ... }