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

ust*_*ion 5 rust serde

我的类型A可以包含任何实现的类型,但是可以trait Trait序列化,尽管实现特征的类型Trait可能不是.在我的情况下,它不能 - 它是一个私人非对称密钥:

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() {}
Run Code Online (Sandbox Code Playgroud)

操场

这出错了:

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`
Run Code Online (Sandbox Code Playgroud)

如果我注释掉A::Variant0,如代码中的内联注释中所述,那么它编译得很好.这让我觉得编译器无法推断出B<T>可序列化,但实际上它能够推断出因为它可以解决的E是可序列化的,这也需要B是可序列化的.

问题出在哪儿?

dto*_*nay 6

在宏扩展期间,编译器尚未确定哪个B内部被引用Variant0或者如何B使用其类型参数.因此,宏观扩张推断出特征界限,这种特征界限可能适用于最常见的情况B,例如B,Box或者是Vec.在这种情况下,序列化B<T>需要T: Serialize和反序列化B<T>需要T: Deserialize<'de>.

您可以提供手写的泛型类型边界来替换推断的边界.

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