派生 Serde 的 Serialize 或 Deserialize 强制泛型类型可序列化,尽管它不需要是 [英] Deriving Serde's Serialize or Deserialize forces generic type to be serialisable although it does not need to be

查看:89
本文介绍了派生 Serde 的 Serialize 或 Deserialize 强制泛型类型可序列化,尽管它不需要是的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My type A, which can contain anything that implements trait Trait, is serialisable, although the type implementing the trait Trait might not be. In my case, it cannot be - it's a private asymmetric 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() {}

游乐场

出现以下错误:

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 也可序列化.

If I comment out A::Variant0, as mentioned in the inline comment in the code, then it compiles fine. This makes me think that the compiler is unable to deduce that B<T> is serialisable, but then it actually is able to deduce that because it can figure out E is serialisable which would require B to be serialisable as well.

问题出在哪里?

推荐答案

在宏扩展期间,编译器尚未确定在 Variant0 中引用了哪个 B 或如何引用B 可以使用它的类型参数.因此,宏扩展推断出的特征边界适用于 B 可能是什么的最常见情况,例如 BBox 或 <代码>Vec.在这些情况下,序列化 B 将需要 T: Serialize 和反序列化 B 将需要 T: Deserialize<'代码>.

During macro expansion the compiler has not yet determined which B is being referred to inside Variant0 or how that B may use its type parameters. As such, macro expansion infers trait bounds that would work for the most common cases of what B might be, like if B were Box or Vec. In those cases serializing B<T> would require T: Serialize and deserializing B<T> would require T: Deserialize<'de>.

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

You can provide handwritten generic type bounds to replace the inferred bounds.

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

这篇关于派生 Serde 的 Serialize 或 Deserialize 强制泛型类型可序列化,尽管它不需要是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆