简体   繁体   English

Rust - 泛型类型的泛型到 vec

[英]Rust - Generic of generic type into vec

I need to create a Vec like this code :我需要像这样创建一个 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());
}

What is the code that I must add instead of "????"?我必须添加什么代码而不是“????”? I've tried Box<dyn Serialize + Deserialize<'a>> but rust tells me "the trait serde::Serialize cannot be made into an object".我试过Box<dyn Serialize + Deserialize<'a>>但 rust 告诉我“特性serde::Serialize不能变成一个对象”。

I'm newbie on rust, so generics are obscure for me, like lifetimes.我是 Rust 的新手,所以泛型对我来说很模糊,就像生命周期一样。 I'm from Java/Typescript.我来自 Java/Typescript。 In Java/Typescript I write:在 Java/Typescript 我写:

let myVec: Vec<TPlugin<?>>;

Regards.问候。

First to focus on the core problem: To have a Vec of heterogenous objects, you must use dynamic dispatch, for example the Box<dyn ...> , which you already used successfully.首先关注核心问题:要拥有一个Vec的异构对象,您必须使用动态调度,例如Box<dyn ...> ,您已经成功使用了它。 But then inside you need another dynamic dispatch and this one is not possible.但是在内部你需要另一个动态调度,而这个是不可能的。 The Box<dyn ...> will end up being a "fat pointer" - one pointer pointing to the data, other pointer pointing to a virtual table for that type. Box<dyn ...>最终将成为一个“胖指针”——一个指针指向数据,另一个指针指向该类型的虚拟表。 Virtual table is generated by the compiler and contains pointer to implementation of every method the type has.虚拟表由编译器生成,包含指向该类型具有的每个方法的实现的指针。 And here comes the problem, look at the Serialize trait:问题来了,看看Serialize trait:

pub trait Serialize {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer;
}

It has one method serialize , but this method is generic over Serializer .它有一个方法serialize ,但是这个方法在Serializer是通用的。 So really there is not one method, but "infinite" amount of methods, one for each possible Serializer .所以真的没有一种方法,而是“无限”数量的方法,每个可能的Serializer The compiler is not able to make virtual table for that, so Serializer can not be made into an (trait) object.编译器无法为此创建虚拟表,因此无法将Serializer制成(特征)对象。

I would suggest you to define your own trait that describes what you want to do with Config and is object safe .我建议你定义你自己的特征,描述你想用Config做什么并且是对象安全的 Perhaps methods for saving and loading with a specific Serializer , toml for example?也许使用特定的Serializer保存和加载的方法,例如toml

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM