我需要创建一个这样的Vec代码:
use serde::{Serialize, Deserialize};
trait TPlugin<'a, Config> where Config : Serialize + Deserialize<'a> {}
#[derive(Serialize, Deserialize)]
struct MyConfig {}
struct MyPlugin1 {
conf: MyConfig,
}
impl TPlugin<MyConfig> for MyPlugin1 {}
impl MyPlugin1 {
pub fn new() -> MyConfig1 {
MyConfig1{}
}
}
fn main() {
let my_vec: Vec<Box<dyn TPlugin<????>>> = Vec::new();
my_vec.push(MyConfig1::new());
my_vec.push(MyConfig2::new());
}
我必须添加的代码是什么????"? 我试过
Box<dyn Serialize + Deserialize<'a>>
,但rust告诉我“这个特性不能变成一个物体”。我是新手,所以仿制药对我来说很模糊,就像我的有生之年一样。我来自Java/Typescript。
我用Java/Typescript编写:
let myVec: Vec<TPlugin<?>>;
当做。
最佳答案
首先要关注核心问题:要拥有一个Vec
的异构对象,必须使用动态调度,例如已经成功使用的Box<dyn ...>
。但在内部,你需要另一个动态调度,而这个调度是不可能的。Box<dyn ...>
最终将成为一个“胖指针”——一个指针指向数据,另一个指针指向该类型的虚拟表。Virtual table由编译器生成,并包含指向该类型所具有的每个方法的实现的指针。问题来了,看看Serialize
特性:
pub trait Serialize {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer;
}
它有一个方法
serialize
,但是这个方法是通用的。因此,实际上没有一种方法,而是“无限”数量的方法,每种方法都有一个。编译器无法为此生成虚拟表,因此无法将Serializer
生成(trait)对象。我建议你定义自己的特质,描述你想用
Serializer
和object safe做什么。例如,使用特定的Serializer
,Config
保存和加载的方法?