rust - 派生 Serde 的序列化或反序列化强制泛型类型可序列化,尽管它不需要是

标签 rust serde

我的类型 A ,它可以包含任何实现 trait Trait 的东西, 是可序列化的,尽管实现特征 Trait 的类型也许不是。在我的例子中,它不可能 - 它是一个私有(private)的非对称 key :

extern crate serde;
#[macro_use]
extern crate serde_derive;

use serde::de::DeserializeOwned;
use serde::Serialize;

trait Trait {
    type SerialisableType: Clone + Serialize + DeserializeOwned;

    fn inner(&self) -> &Self::SerialisableType;
}

#[derive(Serialize, Deserialize)]
enum A<T: Trait> {
    Variant0(B<T>), // *** NOTE: Compiles if this is commented ***
    Variant1(T::SerialisableType),
}

#[derive(Serialize, Deserialize)]
struct B<T: Trait> {
    inner: T::SerialisableType,
}

// ==============================================

struct NonSerialisable {
    serialisable: Serialisable,
}

impl Trait for NonSerialisable {
    type SerialisableType = Serialisable;

    fn inner(&self) -> &Self::SerialisableType {
        &self.serialisable
    }
}

#[derive(Clone, Serialize, Deserialize)]
struct Serialisable(Vec<u8>);

#[derive(Serialize, Deserialize)]
enum E {
    Variant0(A<NonSerialisable>),
    Variant1(B<NonSerialisable>),
}

fn main() {}

playground

这个错误是:

error[E0277]: the trait bound `NonSerialisable: serde::Serialize` is not satisfied
  --> src/main.rs:43:10
   |
43 | #[derive(Serialize, Deserialize)]
   |          ^^^^^^^^^ the trait `serde::Serialize` is not implemented for `NonSerialisable`
   |
   = note: required because of the requirements on the impl of `serde::Serialize` for `A<NonSerialisable>`
   = note: required by `serde::Serializer::serialize_newtype_variant`

error[E0277]: the trait bound `NonSerialisable: serde::Deserialize<'_>` is not satisfied
  --> src/main.rs:43:21
   |
43 | #[derive(Serialize, Deserialize)]
   |                     ^^^^^^^^^^^ the trait `serde::Deserialize<'_>` is not implemented for `NonSerialisable`
   |
   = note: required because of the requirements on the impl of `serde::Deserialize<'_>` for `A<NonSerialisable>`
   = note: required by `serde::de::VariantAccess::newtype_variant`

如果我注释掉 A::Variant0 ,如代码中的内联注释中所述,然后编译正常。这让我认为编译器无法推断出 B<T>是可序列化的,但它实际上能够推断出这一点,因为它可以计算出 E是可序列化的,需要 B也可以序列化。

问题出在哪里?

最佳答案

在宏扩展期间,编译器尚未确定哪个 B在里面被引用Variant0或者如何B可以使用它的类型参数。因此,宏扩展推断出适用于最常见情况的特征边界 B可能是,如果BBoxVec .在那些情况下序列化 B<T>需要 T: Serialize和反序列化 B<T>需要 T: Deserialize<'de> .

您可以提供handwritten generic type bounds替换推断的边界。

#[derive(Serialize, Deserialize)]
#[serde(bound = "")]
enum A<T: Trait> {
    Variant0(B<T>),
    Variant1(T::SerialisableType),
}

关于rust - 派生 Serde 的序列化或反序列化强制泛型类型可序列化,尽管它不需要是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50047334/

相关文章:

c - 将数组从 C 传递给 Rust,尺寸在运行时定义

Rust 特性不满足

json - 同时支持 serde_json::Value 和 cbor_json::Value

json - 使用rust serde反序列化不同的数据结构

rust - 如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

serialization - 如何将 BSON 反序列化为通用对象?

rust - 如何在 Option<T> 中访问 T 而不会导致移动?

c++ - Rust 中从 extern "C"方法返回动态字符串以供 C 或 C++ 使用的最佳方法

rust - 为什么我们不应该在 HashSet::insert 中使用 & ?

concurrency - 在Rust中编写双重检查锁定的正确方法是什么?