Не удается разрешить T: serde :: Deserialize ‹'a› при наследовании Deserialize на универсальной структуре

Я пытаюсь написать структуру, которая наследует serde::Deserialize, но у нее также есть поле, которое должно быть производным serde::Deserialize:

extern crate serde;
#[macro_use]
extern crate serde_derive;

use serde::{Deserialize, Serialize};

#[derive(PartialEq, Serialize, Deserialize)]
pub struct Record<'a, T>
where
    T: 'a + Serialize + Deserialize<'a>,
{
    id: &'a str,
    created_at: &'a str,
    created_by: Option<&'a str>,
    last_updated_at: Option<&'a str>,
    object: &'a T,
}

impl<'a, T> Record<'a, T>
where
    T: 'a + Serialize + Deserialize<'a>,
{
    pub fn new(
        id: &'a str,
        created_at: &'a str,
        created_by: Option<&'a str>,
        last_updated_at: Option<&'a str>,
        object: &'a T,
    ) -> Self {
        Record {
            id,
            created_at,
            created_by,
            last_updated_at,
            object,
        }
    }
}

fn main() {}

Я какое-то время менял код, но не могу скомпилировать эту идею. Ошибка, которую я получаю в данный момент:

error[E0283]: type annotations required: cannot resolve `T: serde::Deserialize<'a>`
 --> src/main.rs:7:32
  |
7 | #[derive(PartialEq, Serialize, Deserialize)]
  |                                ^^^^^^^^^^^
  |
  = note: required by `serde::Deserialize`

person Tarcisio Xavier Gruppi    schedule 21.04.2018    source источник


Ответы (1)


В общем, вам не следует писать границы черт Serde для структур.

rustc --explain E0283 объясняет вашу проблему:

Эта ошибка возникает, когда у компилятора недостаточно информации для однозначного выбора реализации.

Я обнаружил, что использование #[serde(bound()] для объявления границ приводит к компиляции примера:

#[derive(PartialEq, Serialize, Deserialize)]
pub struct Record<'a, T: 'a> {
    id: &'a str,
    created_at: &'a str,
    created_by: Option<&'a str>,
    last_updated_at: Option<&'a str>,
    #[serde(bound(deserialize = "&'a T: Deserialize<'de>"))]
    object: &'a T,
}

В качестве другого решения, поскольку T является общим и может быть справочным, рассмотрите возможность изменения определения Record, чтобы Serde не нуждался в более явном указании:

#[derive(PartialEq, Serialize, Deserialize)]
pub struct Record<'a, T: 'a> {
    id: &'a str,
    created_at: &'a str,
    created_by: Option<&'a str>,
    last_updated_at: Option<&'a str>,
    object: T,
}

impl<'a, T: 'a> Record<'a, T> {
    pub fn new(
        id: &'a str,
        created_at: &'a str,
        created_by: Option<&'a str>,
        last_updated_at: Option<&'a str>,
        object: T,
    ) -> Self {
        Record {
            id,
            created_at,
            created_by,
            last_updated_at,
            object,
        }
    }
}
person attdona    schedule 21.04.2018
comment
Спасибо вам. Я все еще пытаюсь понять, как Rust управляет данными / памятью. Мне будет чему поучиться по вашим ссылкам. ;) - person Tarcisio Xavier Gruppi; 21.04.2018