派生 Serde 的 Serialize 或 Deserialize 强制泛型类型可序列化,尽管它不需要是 [英] Deriving Serde's Serialize or Deserialize forces generic type to be serialisable although it does not need to be
问题描述
我的类型 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
可能是什么的最常见情况,例如 B
是 Box
或 <代码>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屋!