Tôi đang cố gắng thực hiện tuần tự hóa cấu trúc, trong đó các byte cuối cùng sẽ được gửi xuống một đường ống, được xây dựng lại và các phương thức được gọi trên chúng.Làm thế nào để tôi deserialize vào đặc điểm, không phải là một loại cụ thể?
Tôi tạo ra một đặc điểm các cấu trúc sẽ thực hiện cho phù hợp và tôi đang sử dụng serde và serde-cbor cho serialization:
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();
}
Khi tôi cố gắng để tái tạo lại các byte bằng cách sử dụng đặc điểm như các loại (cho rằng tôi sẽ không biết được tiềm ẩn đối tượng đang được gửi), trình biên dịch phàn nàn rằng đặc tính không thực hiện Sized
đặc điểm:
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`
Tôi đoán nó có ý nghĩa vì trình biên dịch không biết cấu trúc được cho là lớn đến mức nào và không biết cách xếp hàng các byte cho nó. Nếu tôi thay đổi dòng mà tôi deserialize đối tượng để xác định cấu trúc kiểu thực tế, nó hoạt động:
let res: Result<Bar, _> = from_reader(&value[..]);
Có một mô hình tốt hơn để đạt được serialization + đa hình hành vi này?
Tôi ... không nghĩ rằng bạn có thể làm điều đó. Bạn không thể phục hồi cấu trúc trừ khi bạn biết loại bê tông của nó, và bạn không thể gọi các phương thức trên nó trừ khi bạn có con trỏ đến vtable của nó - bạn không thể tìm ra trừ khi bạn có quyền truy cập vào loại cụ thể của nó. Bạn có thể serialize một vtable? – trentcl
Có vẻ như vậy, nhưng tôi đã hy vọng một người nào đó sẽ chỉ ra một cái gì đó tôi đang mất tích. Tôi có một giải pháp không thành ngữ cho việc này nhưng thêm sự liên kết vào mã ... vì vậy tôi đang tìm kiếm một cái gì đó tốt hơn. – Dash83
Bạn có chắc bạn muốn đa hình và không đơn giản là một enum? Bạn có cần mã của bạn để làm việc với các loại do người dùng cung cấp không? –