我解决了编译错误:
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde;
use serde::ser::{Serialize, Serializer, SerializeStruct};
#[derive(Serialize)]
struct Card {
sections: Vec<Section>
}
#[derive(Serialize)]
struct Section {
header: String,
widgets: Vec<Box<dyn WidgetTrait>>
}
#[derive(Serialize)]
struct Image {
#[serde(rename = "imageUrl")]
image_url: String
}
#[derive(Serialize)]
struct KeyValue {
#[serde(rename = "topLabel")]
top_label: String,
content: String
}
trait WidgetTrait {}
impl Serialize for WidgetTrait {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
let s = serializer.serialize_struct("???", 3)?;
s.end()
}
}
impl WidgetTrait for Image {}
impl WidgetTrait for KeyValue {}
fn main() {
}
Playground
工作解决方案的步骤:
- 为实现
WidgetTrait
的您的结构体编写as_any()
实现,如如何从trait对象获取具体类型的引用?所述。
- 为类型为
Box<dyn WidgetTrait>
的特性Serialize
添加实现
- 使用
as_any()
和downcast_ref()
将Box<Widget>
向下转换为结构体,以便我们知道类型
- 使用文档中有关如何序列化强类型结构的信息
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde;
use serde::ser::{Serialize, Serializer, SerializeStruct};
use std::any::Any;
#[derive(Serialize)]
struct Card {
sections: Vec<Section>
}
#[derive(Serialize)]
struct Section {
header: String,
widgets: Vec<Box<dyn WidgetTrait>>
}
#[derive(Serialize)]
struct Image {
#[serde(rename = "imageUrl")]
image_url: String
}
#[derive(Serialize)]
struct KeyValue {
#[serde(rename = "topLabel")]
top_label: String,
content: String
}
trait WidgetTrait {
fn as_any(&self) -> &Any;
}
impl Serialize for Box<dyn WidgetTrait> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
return match self.as_any().downcast_ref::<Image>() {
Some(img) => {
let mut widget_serializer = serializer.serialize_struct("Image", 1)?;
widget_serializer.serialize_field("imageUrl", &img.image_url)?;
widget_serializer.end()
},
None => {
let key_value: &KeyValue = match self.as_any().downcast_ref::<KeyValue>() {
Some(k) => k,
None => panic!("Unknown type!")
};
let mut widget_serializer = serializer.serialize_struct("KeyValue", 2)?;
widget_serializer.serialize_field("topLabel", &key_value.top_label)?;
widget_serializer.serialize_field("content", &key_value.content)?;
widget_serializer.end()
}
};
}
}
impl WidgetTrait for Image {
fn as_any(&self) -> &Any {
self
}
}
impl WidgetTrait for KeyValue {
fn as_any(&self) -> &Any {
self
}
}
fn main() {
}
Playground
Section
结构体中使用泛型将不允许您存储实现WidgetTrait
的不同小部件,因为Rust在编译期间单态化泛型。只是提供信息,盒式特征通常是一个好方法,或者根据您的用例选择Rc
。 - jonnyBox<WidgetTrait>
的struct
的类型,以便能够使用强类型的serializer
。 - snowbane