【发布时间】:2019-01-25 06:54:04
【问题描述】:
我有一个与here 描述的用例类似的用例,但略有不同的是,我的解决方案不能用非泛型方法替换泛型方法。这是我拥有的代码 (Rust Playground):
use serde::{de::DeserializeOwned, Serialize};
use serde_json;
trait Serializer {
fn serialize_data<V>(&self, data: &V) -> Result<String, String> where V: Serialize;
fn deserialize_data<V>(&self, ser_data: &str) -> Option<V> where V: DeserializeOwned;
}
struct JsonSerializer {
x: i32 // some member I need to store
}
impl JsonSerializer {
fn new() -> JsonSerializer {
JsonSerializer { x: 1 }
}
}
impl Serializer for JsonSerializer {
fn serialize_data<V>(&self, data: &V) -> Result<String, String> where V: Serialize {
match serde_json::to_string(data) {
Ok(ser_data) => Ok(ser_data),
Err(err) => Err(err.to_string())
}
}
fn deserialize_data<V>(&self, ser_data: &str) -> Option<V> where V: DeserializeOwned {
match serde_json::from_str(ser_data).unwrap() {
Ok(val) => Some(val),
Err(_) => None
}
}
}
// I may want to have more serializer objects like
// YamlSerizlier, BincodeSerializer and so on...
// ...
struct MyMainObject {
serializer: Box<Serializer>
}
impl MyMainObject {
fn new() -> MyMainObject {
MyMainObject { serializer: Box::new(JsonSerializer::new()) }
}
fn do_something(&self) {
println!("{}", self.serializer.serialize_data(&1));
println!("{}", self.serializer.serialize_data(&String::from("MY STRING")));
}
}
fn main() {
let my_main_object = MyMainObject::new();
my_main_object.do_something();
}
如上一个问题所述,编译此代码时出现错误the trait `Serializer` cannot be made into an object,因为它具有泛型方法:
Compiling playground v0.0.1 (/playground)
error[E0038]: the trait `Serializer` cannot be made into an object
--> src/main.rs:42:5
|
42 | serializer: Box<Serializer>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Serializer` cannot be made into an object
|
= note: method `serialize_data` has generic type parameters
= note: method `deserialize_data` has generic type parameters
但就我而言,我希望这些方法保持通用,以便我可以序列化/反序列化任何类型的数据。
所以我的问题是如何保持动态调度模式并仍然使其工作,这意味着我想要MyMainObject 中的Serializer trait 成员,我可以使用任何类型的序列化程序对象(Json、Yaml 等)进行初始化.),然后在MyMainObject 中调用serializer.serialize_data() 或serializer.deserialize_data()。
如果这不可能,您可以建议的最佳选择是什么?
编辑:
我需要一个适用于不同类型序列化程序的解决方案,列出这些:
【问题讨论】:
-
This library 不久前在 Rust 的 subreddit 上宣布。我没有仔细研究它,但它可能是你想要的
-
如果我理解正确的话,这个库可以实现特征对象的序列化/反序列化,但我正在寻找的是一种在相同特征下实现不同序列化程序的方法,或者至少是接近于的设计那
-
哦,对了,应该更仔细地阅读这个问题,抱歉)。嗯,总是有 enum 方法,但这是很多样板文件,而且可扩展性不是很好。
-
你能详细说明一下这个选项吗?
-
将所有序列化程序包装在一个枚举中,并使用枚举而不是
Box<Serializer>。主要的缺点是您失去了 trait 对象提供的灵活性 - 每当您想要添加对新序列化程序的支持时,您需要向枚举添加一个变体,并且您的库的用户(如果它是一个)可以' t 只是插入他们自己的序列化程序而没有类似的解决方法。但它适用于一般的东西。