如何为装箱的特征对象实现`serde :: Serialize`? [英] How to implement `serde::Serialize` for a boxed trait object?

查看:353
本文介绍了如何为装箱的特征对象实现`serde :: Serialize`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试为结构创建通用向量时遇到问题. 这是我的第一次尝试:

I ran into a problem trying to create a generic vector for a struct. This was my first attempt:

#[derive(Serialize)]
struct Card {
    sections: Vec<Section<WidgetTrait>>
}

#[derive(Serialize)]
struct Section<T: WidgetTrait> {
    header: String,
    widgets: Vec<T>
}

这使我陷入一个错误,未实现Sized,并且在编译时不知道WidgetTrait大小.

This has brought me to an error that Sized is not implemented and WidgetTrait size is not known at compile time.

我的下一个尝试是像这样使用Box<WidgetTrait>:

My next attempt was to use Box<WidgetTrait> like so:

#[derive(Serialize)]
struct Section {
    header: String,
    widgets: Vec<Box<WidgetTrait>>
}

游乐场

这导致我出错:

error[E0277]: the trait bound `WidgetTrait: serde::Serialize` is not satisfied
  --> src/main.rs:11:10
   |
11 | #[derive(Serialize)]
   |          ^^^^^^^^^ the trait `serde::Serialize` is not implemented for `WidgetTrait`
   |
   = note: required because of the requirements on the impl of `serde::Serialize` for `std::boxed::Box<WidgetTrait>`
   = note: required because of the requirements on the impl of `serde::Serialize` for `std::vec::Vec<std::boxed::Box<WidgetTrait>>`
   = note: required by `serde::ser::SerializeStruct::serialize_field`

我的目标是使Section结构中的小部件向量能够接受实现WidgetTrait特征的不同类型的小部件,就像使用界面一样.

My goal is for the widgets vector in Section struct to be able to accept different types of widgets that implement WidgetTrait trait, just like you would with an interface.

推荐答案

要序列化Serde特征对象,应使用 erased-serde .

For serializing Serde trait objects you should use erased-serde.

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate erased_serde;

extern crate serde;
extern crate serde_json;

#[derive(Serialize)]
struct Card {
    sections: Vec<Section>,
}

#[derive(Serialize)]
struct Section {
    header: String,
    widgets: Vec<Box<WidgetTrait>>,
}

#[derive(Serialize)]
struct Image {
    image_url: String,
}

#[derive(Serialize)]
struct KeyValue {
    top_label: String,
    content: String,
}

trait WidgetTrait: erased_serde::Serialize {}
impl WidgetTrait for Image {}
impl WidgetTrait for KeyValue {}

serialize_trait_object!(WidgetTrait);

fn main() {
    let card = Card {
        sections: vec![
            Section {
                header: "text".to_owned(),
                widgets: vec![
                    Box::new(Image {
                        image_url: "img".to_owned(),
                    }),
                    Box::new(KeyValue {
                        top_label: "text".to_owned(),
                        content: "text".to_owned(),
                    }),
                ],
            },
        ],
    };

    println!("{}", serde_json::to_string_pretty(&card).unwrap());
}

这篇关于如何为装箱的特征对象实现`serde :: Serialize`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆