如何派生serde :::反序列化具有生命周期成员的结构

时间:2019-08-28 12:45:32

标签: rust lifetime serde

如何为内部寿命不同或相等的对象的结构派生Deserialize

playground

#[derive(Default, Debug, serde::Deserialize, serde::Serialize)]
struct B<'a> {
    b: &'a str,
}

#[derive(Default, Debug, serde::Deserialize, serde::Serialize)]
struct C<'a> {
    c: &'a str,
}

#[derive(Default, Debug, serde::Deserialize, serde::Serialize)]
struct A<'a> {
    b: B<'a>,
    c: C<'a>,
}

fn main() {
}

Rustc说这是不可能的:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
  --> src/main.rs:13:5
   |
13 |     b: B<'a>,
   |     ^
   |
note: first, the lifetime cannot outlive the lifetime 'de as defined on the impl at 11:26...
  --> src/main.rs:11:26
   |
11 | #[derive(Default, Debug, serde::Deserialize, serde::Serialize)]
   |                          ^^^^^^^^^^^^^^^^^^
   = note: ...so that the types are compatible:
           expected _IMPL_SERIALIZE_FOR_B::_serde::de::SeqAccess<'_>
              found _IMPL_SERIALIZE_FOR_B::_serde::de::SeqAccess<'de>
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 12:10...
  --> src/main.rs:12:10
   |
12 | struct A<'a> {
   |          ^^
   = note: ...so that the types are compatible:
           expected _IMPL_SERIALIZE_FOR_B::_serde::Deserialize<'_>
              found _IMPL_SERIALIZE_FOR_B::_serde::Deserialize<'_>

我不知道是什么原因导致了这个问题以及如何解决。 有a similar question,但其答案并未涵盖这种情况。

1 个答案:

答案 0 :(得分:5)

serde的生命周期非常复杂,可以使您反序列化而无需复制过多的数据。在https://serde.rs/lifetimes.html

中有描述

除了&str&[u8]以外,serde不接受隐式借用。

对于其他结构参数,如果要从反序列化器中借用,则必须明确,这是使用特殊的#[serde(borrow)]属性完成的:

#[derive(Default, Debug, serde::Deserialize, serde::Serialize)]
struct A<'a> {

    #[serde(borrow)]
    b: B<'a>,

    #[serde(borrow)]
    c: C<'a>,
}