Generics 如何创建可以用Serde序列化并保留类型信息的泛型结构?

Generics 如何创建可以用Serde序列化并保留类型信息的泛型结构?,generics,serialization,rust,traits,serde,Generics,Serialization,Rust,Traits,Serde,我想使用Serde序列化一个通用的数据结构 my library的用户应该能够提供自己的结构来实现序列化和反序列化。我应该能够获取他们序列化数据时使用的值的原始类型信息 我该怎么做呢 我试过这样的方法: #[derive(Serialize, Deserialize)] struct Message<V> { key: Key, value: V, } #[派生(序列化、反序列化)] 结构消息{ 钥匙:钥匙, 值:V, } 我想在反序列化数据后返回V的类型 是这样

我想使用Serde序列化一个通用的数据结构

my library的用户应该能够提供自己的结构来实现
序列化
反序列化
。我应该能够获取他们序列化数据时使用的值的原始类型信息

我该怎么做呢

我试过这样的方法:

#[derive(Serialize, Deserialize)]
struct Message<V> {
    key: Key,
    value: V,
}
#[派生(序列化、反序列化)]
结构消息{
钥匙:钥匙,
值:V,
}
我想在反序列化数据后返回
V
的类型

是这样做的,还是我偏离了轨道


我希望用户能够扩展可能的值/类型。我想要枚举的行为,但是用户可以灵活地添加自己的结构作为候选结构。与类似,但它们都需要唯一的ID。

我非常确定,从一般意义上讲,这是完全不可能的

每种类型都能够控制自己的序列化。这意味着多个类型可能最终序列化为相同的值:

您可以尝试在序列化数据中建立标识类型的标记,但最终会出现相同的问题:始终存在冲突的可能性

更根本的是,这种概念在Rust中是无效的,因为每个类型在编译时都必须有一个已知的大小。无法反序列化为大小未知的变量

同样重要的是,您会为泛型
V
提供什么类型?编译代码时,不能“忘记”指定所有泛型类型

正因为如此,通常这样的事情都不会发生。如果用户使用具体类型调用序列化代码,则可以使用相同的具体类型调用反序列化代码

我想要枚举的行为,但是要让用户能够灵活地添加自己的结构

这听起来像是一个特质对象

另见:


    • 实现这种想法的最佳方法是限制V的类型,然后使用结构名称作为标识模块类型+字符串的方法

      范例

      pub struct Message<V: Serialize + Deserialize> {
           key: keytype,
           value: V,
           crate_path: String
      }
      
      pub结构消息{
      键:键类型,
      值:V,
      板条箱路径:字符串
      }
      

      然后使用类似sha的方法为结构名生成哈希,反序列化以检查结构名。

      您可能想看看@SørenMortensen,我认为这与我所追求的类似,但我希望用户为值提供反序列化,并有可能传递不同类型的泛型。@SørenMortensen,或者可能比我刚开始的时候强。但它能跟踪我用的是什么类型的吗?或者我需要告诉rust什么样的
      Outer
      ,或者可以推断出来吗?让我们来看看。或者提供信息/回答您的问题吗?
      pub struct Message<V: Serialize + Deserialize> {
           key: keytype,
           value: V,
           crate_path: String
      }