我想要做的結構序列化,其中的字節最終將被髮送到一個管道,重建和調用方法。如何反序列化爲特徵,而不是具體類型?
我創建了一個特點,這些結構將實施適當的和我使用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
你確定你想要多態而不僅僅是一個枚舉嗎?你需要你的代碼來處理用戶提供的類型嗎? –