如何为装箱的特征对象实现`serde :: Serialize`? [英] How to implement `serde::Serialize` for a boxed trait object?
问题描述
我在尝试为结构创建通用向量时遇到问题. 这是我的第一次尝试:
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屋!