rust - 将 serde 与 trait 对象一起使用
问题描述
我正在尝试使用 serde 序列化特征对象。我看了看
- 如何为盒装特征对象实现`serde::Serialize`?
- 我们如何编写一个通用函数来检查 Serde 序列化和反序列化?
- https://github.com/dtolnay/erased-serde
但我不明白如何把这些碎片放在一起。请告诉我如何进行此操作。
这段代码模仿了Rust 编程语言中的示例:
use serde::Serialize; // 1.0.126
trait Paint: Serialize {
fn paint(&self) -> String;
}
#[derive(Serialize)]
struct Pen {
color: String,
}
#[derive(Serialize)]
struct Brush {
color: String,
}
impl Paint for Pen {
fn paint(&self) -> String {
return format!("Pen painting with color {}", self.color);
}
}
impl Paint for Brush {
fn paint(&self) -> String {
return format!("Brush painting with color {}", self.color);
}
}
#[derive(Serialize)]
struct Canvas {
height: f32,
width: f32,
tools: Vec<Box<dyn Paint>>,
}
impl Paint for Canvas {
fn paint(&self) -> String {
let mut s = String::new();
for tool in &self.tools {
s.push_str("\n");
s.push_str(&tool.paint());
}
return s;
}
}
fn main() {
let pen = Pen {
color: "red".to_owned(),
};
let brush = Brush {
color: "blue".to_owned(),
};
let canvas = Canvas {
height: 12.0,
width: 10.0,
tools: vec![Box::new(pen), Box::new(brush)],
};
println!("{}", canvas.paint());
serde_json::to_string(&canvas).unwrap();
}
由于对象安全规则,代码无法编译:
error[E0038]: the trait `Paint` cannot be made into an object
--> src/main.rs:33:12
|
33 | tools: Vec<Box<dyn Paint>>,
| ^^^^^^^^^^^^^^^^^^^ `Paint` cannot be made into an object
|
= help: consider moving `serialize` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.126/src/ser/mod.rs:247:8
|
247 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
| ^^^^^^^^^ ...because method `serialize` has generic type parameters
|
::: src/main.rs:3:7
|
3 | trait Paint: Serialize {
| ----- this trait cannot be made into an object...
我知道特征对象不能具有带有泛型参数的方法,但在我的情况下,我只需要将Canvas
结构序列化为 JSON。有什么我可以做的吗?
理想的序列化输出将是
{
"Canvas": {
"height": 12.0,
"width": 10.0,
"tools": {
"Pen": {
"color": "red"
},
"Brush": {
"color": "blue"
}
}
}
}
解决方案
推荐阅读
- r - 如何在 R 循环中动态更新传递给 fable 包中 ARIMA 函数的变量名称,?
- c++ - 文件打不开
- jenkins - 仅在 gitlab 合并请求上触发多分支管道
- c# - .Net core 2.2 到 3.x 迁移:Url.Action 生成错误的 URL,端点路由已停用
- codeigniter - Codeigniter 数据库错误号:1048,它说即使列不为空,列“I”也不能为空
- javascript - 使用 Jpeg-autorotate npm 模块基于 EXIF Data javascript 旋转图像
- javascript - 做出反应。可编辑表
- javascript - 如何使用带有 bitbucket 访问令牌的纯 javascript/(ajax) 来获取 JSON 数据?
- c++ - BROWSEINFO 在 Windows 10 上获取选择目录的问题
- google-smart-home - 带有 lambda 函数的谷歌智能家居操作