【问题标题】:Rust - Generic of generic type into vecRust - 泛型类型的泛型到 vec
【发布时间】:2019-11-24 18:56:26
【问题描述】:

我需要像这样创建一个 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&lt;dyn Serialize + Deserialize&lt;'a&gt;&gt;,但rust告诉我“特征serde::Serialize不能变成一个对象”。

我是 Rust 的新手,所以泛型对我来说是模糊的,就像生命周期一样。我来自 Java/Typescript。 在 Java/Typescript 我写:

let myVec: Vec<TPlugin<?>>;

问候。

【问题讨论】:

    标签: generics vector rust


    【解决方案1】:

    首先要关注核心问题:要拥有一个Vec的异构对象,你必须使用动态调度,例如你已经成功使用的Box&lt;dyn ...&gt;。但是在里面你需要另一个动态调度,而这个是不可能的。 Box&lt;dyn ...&gt; 最终将成为一个“胖指针”——一个指向数据的指针,另一个指向该类型的虚拟表的指针。 Virtual table 由编译器生成,并包含指向该类型具有的每个方法的实现的指针。问题来了,看看Serialize trait:

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

    它有一个方法serialize,但是这个方法是通用的Serializer。所以真的没有一种方法,而是“无限” 数量的方法,每个可能的Serializer 一个。编译器无法为此创建虚拟表,因此无法将Serializer 制成(特征)对象。

    我建议您定义自己的特征来描述您想用Config 做什么,并且是object safe。例如使用特定的Serializertoml 进行保存和加载的方法?

    【讨论】:

    • 感谢您的解释。我怀疑事情是这样的。明天我会试试的。多年来,我没有用任何语言进行内存操作,我需要努力! :)
    猜你喜欢
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    相关资源
    最近更新 更多