我正在尝试创建一种特征,并为所有非引用类型提供一种实现,为所有引用类型提供另一种实现。
这无法编译:
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
可以是任何东西,所以Foo
每当出现重叠(冲突)T
第一个 impl 是&'a mut U
,因为第二个 impl 也涵盖了这种情况(当T
is U
).
The Clone
版本有效只是因为&mut
引用从未实现Clone
,所以之间没有重叠T where T: Clone
and &'a mut T
.² 如果您尝试实施Bar
对于不可变的(&
) 引用,你会再次发生冲突,因为不可变引用do实施Clone
.
[没有它我怎样才能让它工作?
如果“它”指的是引用类型的一种实现,而非引用类型的另一种实现,则在 Rust 中这是不可能的,原因与您无法以一种方式实现特征的原因相同struct
s 和另一种方式enum
s:根本没有办法表达它(在当前的 Rust 中)。
一种常见的模式是might对您来说,为您需要的任何非引用类型单独实现您的特征,然后添加一个“blanket 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如果这不是你想要的。
² The where T: Clone + 'static
条款并不重要,因为&'a mut T
永远不会Clone
无论T
本身是或不是。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)