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

查看:20
本文介绍了如何为盒装特征对象实现`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 trait 对象,你应该使用 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天全站免登陆