Generics 一般特征对象向量
(这是我第二次尝试追踪我的确切问题。请参阅编辑历史记录) 我有一个简单的通用特性和两种不同的实现:Generics 一般特征对象向量,generics,types,enums,rust,polymorphism,Generics,Types,Enums,Rust,Polymorphism,(这是我第二次尝试追踪我的确切问题。请参阅编辑历史记录) 我有一个简单的通用特性和两种不同的实现: pub trait MyTrait<T=Self> where T: MyTrait { } struct Impl1; impl MyTrait for Impl1 { } struct Impl2; impl MyTrait for Impl2 { } 每个MyTrait对象都会消耗自身,并可能导致MyEnum::a包含另一个MyTrait对象,或者MyEnum::B泛型的东
pub trait MyTrait<T=Self> where T: MyTrait {
}
struct Impl1;
impl MyTrait for Impl1 {
}
struct Impl2;
impl MyTrait for Impl2 {
}
每个
MyTrait
对象都会消耗自身,并可能导致MyEnum::a
包含另一个MyTrait
对象,或者MyEnum::B
泛型的东西不管特征、类型或函数是否是可以处理的代码,但仅仅是在替换它们时生成代码的模板。所以它们不是“对象安全的”,也就是说,您不能将它们用于动态引用和智能指针的类型。您只能使用它们的特定实例
MyTrait
是通用的,因此您不能使用&dyn MyTrait
或框。您只能使用&dyn MyTrait
或框
您确实有参数的默认值,但是Self
是特殊的,因为Self
是实现特征的类型,因此只有在impl
定义中才有意义。但不是在试图声明Vec
的自由函数中。这就是为什么它不能被编译
另外,由于自身的特殊性,impl MyTrait for Impl1
被删除为impl MyTrait for Impl1
,impl MyTrait for Impl2
被删除为impl MyTrait for Impl2
。由于MyTrait
与MyTrait
是不同的特征,因此Impl1
和Impl2
没有可用于将它们装箱并放入公共向量中的公共特征
动态多态性需要一个具体的、非泛型的trait。在MyTrait
中泛型参数的用途是什么?在特质中你在哪里使用了T?编辑表明你脑子里有一个问题,但你没有解释,只是展示了具体的、失败的、试图解决它的尝试。试着描述更高层次的问题,这样我们就可以试着引导您找到对此首选的解决方案dyn Trait
和enum
s各有优缺点,您应该使用哪一种取决于您更广泛的需求。广告编辑:但实现什么?混合使用静态(泛型)和动态(特征对象、枚举)多态性效果不佳。你需要想出另一个表示法,如果他们不知道它应该是什么,没有人能帮助你。
fn foo() {
let mut traits: Vec<Box<MyTrait>> = Vec::new();
traits.push(Box::new(Impl1{}));
traits.push(Box::new(Impl2{}));
}
error[E0393]: the type parameter `T` must be explicitly specified
--> src/main.rs:25
|
25 | let mut traits: Vec<Box<MyTrait>> = Vec::new();
| ^^^^^^^ missing reference to `T`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
enum MyEnum<T: MyTrait> {
A(T),
B
}
pub trait MyTrait<T=Self> where T: MyTrait {
fn do_stuff(self) -> MyEnum<T>;
}
struct Impl1;
impl MyTrait for Impl1 {
fn do_stuff(self) -> MyEnum<Impl1> {
MyEnum::A(self)
}
}
struct Impl2;
impl MyTrait for Impl2 {
fn do_stuff(self) -> MyEnum<Impl2> {
MyEnum::B
}
}