我的代码库中出现了这样一种情况:一个函数带有一个装箱的 trait 对象,它调用了一个需要该 trait 实现者的函数,结果出现了如下所示的错误消息。由于某种原因,Box 默认并没有实现 Trait。
use std::any::Any;
trait SubTrait: DynClone {}
trait DynClone: Any {
fn dyn_clone(&self) -> Box<dyn DynClone>;
}
impl<T: Any + Clone + 'static> DynClone for T {
fn dyn_clone(&self) -> Box<dyn DynClone> {
Box::new(Clone::clone(self))
}
}
fn test_outer() {
test::<Box<dyn SubTrait>>();
}
fn test<L: SubTrait>() {}
error[E0277]: the trait bound `Box<(dyn SubTrait + 'static)>: SubTrait` is not satisfied
--> src\ecs\schedule.rs:124:9
|
124 | test::<Box<dyn SubTrait>>();
| ^^^^^^^^^^^^^^^^^ the trait `SubTrait` is not implemented for `Box<(dyn SubTrait + 'static)>`
|
我不完全明白为什么会这样,但我对一个恰好有效的修复方法感到更困惑
impl DynClone for Box<dyn SubTrait> {
fn dyn_clone(&self) -> Box<dyn DynClone> {
(self as &dyn DynClone).dyn_clone()
}
}
impl SubTrait for Box<dyn SubTrait> {}
我尝试过这个,完全预料到它会因为冲突的实现而被拒绝,但由于某种原因它被接受了。
为什么这些实现并不冲突?
impl DynClone for Box<dyn SubTrait> {
fn dyn_clone(&self) -> Box<dyn DynClone> {
(self as &dyn DynClone).dyn_clone()
}
}
impl<T: Any + Clone + 'static> DynClone for T {
fn dyn_clone(&self) -> Box<dyn DynClone> {
Box::new(Clone::clone(self))
}
}
我知道这不是因为 T 上的特征边界,因为 Rust 在检查冲突时不会考虑特征边界或 where 子句。
我甚至验证了 T 上的特征界限不是用另一种非克隆类型修复的,这导致了此错误消息。
use std::sync::mpsc::Receiver;
impl DynClone for Receiver<()> {
fn dyn_clone(&self) -> Box<dyn DynClone> {
Box::new(25_i32)
}
}
error[E0119]: conflicting implementations of trait `schedule::test::DynClone` for type `std::sync::mpsc::Receiver<()>`
--> src\ecs\schedule.rs:138:1
|
117 | impl<T: Any + Clone + 'static> DynClone for T {
| --------------------------------------------- first implementation here
...
138 | impl DynClone for Receiver<()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::sync::mpsc::Receiver<()>`
|
= note: upstream crates may add a new impl of trait `std::clone::Clone` for type `std::sync::mpsc::Receiver<()>` in future versions
有人能解释一下这里发生了什么吗?