2017-05-28 12 views
10

Tôi đang cố gắng giải quyết vấn đề tuần tự hóa và deserializing Box<SomeTrait>. Tôi biết rằng trong trường hợp của một hệ thống phân cấp loại khép kín, cách được đề nghị là sử dụng một enum và không có vấn đề với serialization của họ, nhưng trong trường hợp của tôi bằng cách sử dụng enums là một giải pháp không phù hợp.Làm thế nào để deserialization của các đối tượng đặc điểm đa hình được thêm vào trong Rust nếu ở tất cả?

Lúc đầu, tôi đã cố gắng sử dụng Serde vì đây là cơ chế tuần tự hóa Rust. Serde có khả năng tuần tự hóa Box<X> nhưng không phải trong trường hợp khi X là một đặc điểm. Không thể triển khai đặc điểm Serialize cho các đối tượng đặc điểm vì nó có các phương pháp chung. Vấn đề cụ thể này có thể được giải quyết bằng cách sử dụng erased-serde để việc tuần tự hóa Box<SomeTrait> có thể hoạt động.

Vấn đề chính là giải tuần tự hóa. Để deserialize loại đa hình bạn cần phải có một số đánh dấu loại trong dữ liệu serialized. Dấu này phải được deserialized đầu tiên và sau đó được sử dụng để tự động nhận được hàm sẽ trả về Box<SomeTrait>.

std::any::TypeId có thể được sử dụng làm loại điểm đánh dấu, nhưng vấn đề chính là cách tự động nhận hàm deserialization. Tôi không xem xét tùy chọn đăng ký một chức năng cho từng loại đa hình nên được gọi thủ công trong quá trình khởi tạo ứng dụng.

Tôi biết hai cách có thể để làm điều đó:

  1. Ngôn ngữ có phản ánh thời gian chạy như C# có thể sử dụng nó để có được phương pháp deserialization.
  2. Trong C++, thư viện ngũ cốc sử dụng phép thuật của các đối tượng tĩnh để đăng ký deserializer trong một bản đồ tĩnh tại thời gian khởi tạo thư viện.

Nhưng không có tùy chọn nào trong số này có sẵn trong Rust. Làm thế nào có thể deserialization của các đối tượng đa hình được thêm vào trong Rust nếu ở tất cả?

+1

"Nhưng trong trường hợp của tôi sử dụng enums là giải pháp không phù hợp". Chúng ta có thể biết tại sao không? Có vẻ như toàn bộ vấn đề sẽ biến mất khi sử dụng enum. Lưu ý rằng loại xóa trong 'erased_serde' xảy ra tại' Deserializer', không phải trên đối tượng đang được deserialized. –

+1

"Chúng ta có thể biết tại sao không?" Tôi đang cố gắng có số lượng phụ thuộc tối thiểu. Tôi có một đặc điểm trong một số mô-đun rất nhỏ và rất cơ bản và rất nhiều mã phụ thuộc vào nó. Và tôi muốn có từng sự triển khai đặc điểm này trong một mô-đun riêng biệt. Ngoài ra còn có một nhược điểm khác khi sử dụng –

+1

Xin lỗi, tôi đã vô tình đăng bình luận trước khi nó được hoàn thành. Ngoài ra còn có nhược điểm khác của việc sử dụng enums: nếu bạn có cùng một phương thức trong tất cả các kiểu con enum để gọi nó trên enum bạn phải thêm 'match' xây dựng với các trường hợp tương tự cho mỗi loại. "loại erasure trong erased_serde xảy ra tại Deserializer, không phải trên đối tượng được deserialized" Có, tôi biết điều đó. Tôi đã đề cập trong câu hỏi rằng erased_serder không giải quyết vấn đề với deserialization, chỉ với serialization. –

Trả lời

0

Tất cả thư viện của bạn có thể cung cấp thường lệ đăng ký, được bảo vệ bởi std::sync::Once, đăng ký số nhận dạng vào một số static mut phổ biến, nhưng rõ ràng là chương trình của bạn phải gọi tất cả.

Tôi không biết liệu TypeId có mang lại giá trị nhất quán giữa các lần biên dịch lại với các phụ thuộc khác nhau hay không.

Các vấn đề liên quan