【问题标题】:How to derive serde::Deserialize for a struct with members with lifetimes [duplicate]如何为具有生命周期的成员的结构派生 serde::Deserialize [重复]
【发布时间】:2019-08-28 12:45:32
【问题描述】:

我如何为一个结构派生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,但它的答案不包括这种情况。

【问题讨论】:

  • 我认为是因为serde::Deserializeserde::Serialize,删除它们可以解决问题。不知道如何保持这些特征没有错误
  • 更简单的复制:play.rust-lang.org/…
  • 这似乎有效:play.rust-lang.org/…
  • @Davichete 这里的主要问题是使用 &amp;str 而不是 String :) 对象
  • @VictorPolevoy 请注意,如果字符串包含转义字符,它将不起作用 -> 解串器必须取消转义它们 -> 它必须是拥有的 (String)。 Playground.

标签: rust lifetime serde


【解决方案1】:

serde 的生命周期非常复杂,可以让您在不复制不必要的数据的情况下进行反序列化。在https://serde.rs/lifetimes.html中有描述

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

对于其他结构体参数,如果你想从反序列化器中借用,你必须是显式的,这是使用一个特殊的#[serde(borrow)]属性来完成的:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 2010-12-12
    相关资源
    最近更新 更多