我想要做的结构序列化,其中的字节最终将被发送到一个管道,重建和调用方法。如何反序列化为特征,而不是具体类型?
我创建了一个特点,这些结构将实施适当的和我使用SERDE和SERDE-CBOR序列化:
extern crate serde_cbor;
#[macro_use]
extern crate serde_derive;
extern crate serde;
use serde_cbor::ser::*;
use serde_cbor::de::*;
trait Contract {
fn do_something(&self);
}
#[derive(Debug, Serialize, Deserialize)]
struct Foo {
x: u32,
y: u32,
}
#[derive(Debug, Serialize, Deserialize)]
struct Bar {
data: Vec<Foo>,
}
#[derive(Debug, Serialize, Deserialize)]
struct Baz {
data: Vec<Foo>,
tag: String,
}
impl Contract for Bar {
fn do_something(&self) {
println!("I'm a Bar and this is my data {:?}", self.data);
}
}
impl Contract for Baz {
fn do_something(&self) {
println!("I'm Baz {} and this is my data {:?}", self.tag, self.data);
}
}
fn main() {
let data = Bar { data: vec![Foo { x: 1, y: 2 }, Foo { x: 3, y: 4 }, Foo { x: 7, y: 8 }] };
data.do_something();
let value = to_vec(&data).unwrap();
let res: Result<Contract, _> = from_reader(&value[..]);
let res = res.unwrap();
println!("{:?}", res);
res.do_something();
}
当我试图重建使用特征作为类型字节(假设我不知道哪个基础对象被发送),编译器会抱怨的特质没有实现Sized
特点:
error[E0277]: the trait bound `Contract: std::marker::Sized` is not satisfied --> src/main.rs:52:15 | 52 | let res: Result<Contract, _> = from_reader(&value[..]); | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Sized` is not implemented for `Contract` | = note: `Contract` does not have a constant size known at compile-time = note: required by `std::result::Result`
我想这是有道理的,因为编译器不知道结构应该有多大,不知道如何排列它的字节。如果我改线,我反序列化对象指定实际的结构类型,它的工作原理:
let res: Result<Bar, _> = from_reader(&value[..]);
有没有更好的方式来实现这一系列化+多态行为?
我......不认为你能做到这一点。除非你知道它的具体类型,否则你不能恢复这个结构体,除非你有一个指向它的vtable的指针,否则你不能调用它的方法 - 除非你有权访问它的具体类型,否则你无法弄清楚。你可以序列化一个Vtable吗? – trentcl
似乎是这样,但我希望有人会指出我失踪的东西。我有一个非惯用的解决方案,但增加了耦合到代码...所以我正在寻找更好的东西。 – Dash83
你确定你想要多态而不仅仅是一个枚举吗?你需要你的代码来处理用户提供的类型吗? –