在使用特征层次结构时,我遇到了以下问题:特征(用作特征对象)应定义一个返回其自身类型的函数。当然,Self
不能使用,因为每个子类型会有所不同。相反,特征应该返回特征对象的类型,例如:
trait MySpecialTrait {
fn clone(&self) -> Box<dyn MySpecialTrait>;
}
到目前为止,这可行。但是现在我想在其自己的通用特征中提取此功能,以便能够编写仅依赖于特征属性的通用代码,如下所示:
trait Cloneable<Output: ?Sized> {
fn clone(&self) -> Box<Output>;
}
trait MySpecialTrait: Cloneable<dyn MySpecialTrait> {
fn something(&self);
}
fn clone_all<T>(data: &Vec<Box<T>>) -> Vec<Box<T>>
where T: ?Sized + Cloneable<T>
{
data.iter().map(|x|x.clone()).collect()
}
但是此代码会产生以下错误:
error[E0391]: cycle detected when computing the supertraits of `MySpecialTrait`
--> src\main.rs:28:1
|
28 | trait MySpecialTrait: Cloneable<dyn MySpecialTrait> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: ...which again requires computing the supertraits of `MySpecialTrait`, completing the cycle
note: cycle used when collecting item types in top-level module
--> src\main.rs:28:1
|
28 | trait MySpecialTrait: Cloneable<dyn MySpecialTrait> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
使用类似的关联类型不会更改任何内容:
trait Cloneable {
type Output;
fn clone(&self) -> Box<Self::Output>;
}
trait MySpecialTrait: Cloneable<Output = dyn MySpecialTrait> {
fn something(&self);
}
有人可以向我解释为什么会有周期吗?我了解在一般情况下,trait A: B
的{{1}}的超性才能计算出B
的超性,所以
A
无法工作。但是在这种情况下,trait A: B {}
trait B: A {}
仅在通用类型参数中被引用,那么为什么需要计算MySpecialTrait
的超特性?
除此之外,是否有解决此问题的方法?
修改
我不希望Cloneable<dyn MySpecialTrait>
仅适用于clone_all
的所有具体子类型,也不希望适用于所有特征类型,例如我想用Cloneable<T>
类型的参数调用clone_all
。