Как мне объявить структуру, которая содержит какую-либо десериализуемую / сериализуемую структуру? - PullRequest
1 голос
/ 30 июня 2019

Я пытаюсь объявить структуру, которая содержит другую структуру любого данного типа, которая может быть Deserialize и Serialize.

#[derive(Debug, Serialize, Deserialize)]
pub struct Foo<T: Deserialize + Serialize> {
    pub data: T,
}

Rust детская площадка .

Для этого я попытался использовать границы черт, используя такие черты, как DeserializeOwned или Deserialize. Оба сбой во время компиляции со следующими ошибками:

error[E0283]: type annotations required: cannot resolve `T: serde::Deserialize<'de>`
 --> src/main.rs:9:28
  |
9 | #[derive(Debug, Serialize, Deserialize)]
  |                            ^^^^^^^^^^^
  |
  = note: required by `serde::Deserialize`
error[E0637]: `&` without an explicit lifetime name cannot be used here
  --> src/main.rs:10:19
   |
10 | pub struct Foo<T: Deserialize + Serialize> {
   |                   ^^^^^^^^^^^ explicit lifetime name needed here

Я столкнулся с ошибками при попытке добавить время жизни, поскольку я не использую хранение ссылки, а значение.

Какой самый идиоматический способ объявления этого типа структуры?

Ответы [ 2 ]

1 голос
/ 30 июня 2019

Только не устанавливайте границы для типа:

use serde::{Deserialize, Serialize}; // 1.0.91

#[derive(Debug, Serialize, Deserialize)]
pub struct Foo<T> {
    pub data: T,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Boo {
    pub a: i64,
}

fn main() {
    let data = Boo { a: 1 };
    let wrap = Foo { data };
    println!("{:?}", wrap);
}

Затем установите границы для методов, где вам нужно такое поведение:

fn use_it<T>(foo: Foo<T>)
where
    Foo<T>: Serialize,
{
    // ...
}
1 голос
/ 30 июня 2019

Я нашел решение благодаря участнику Rust Discord, который направил меня к следующей проблеме Github .Хитрость заключается не в том, чтобы использовать границы признаков, а в атрибутах.

#[derive(Debug, Serialize, Deserialize)]
pub struct Foo<T> {
    #[serde(bound(
        serialize = "T: Serialize",
        deserialize = "T: Deserialize<'de>",
    ))]
    pub data: T,
}
...