Generics 将泛型写入文件

Generics 将泛型写入文件,generics,file-io,rust,Generics,File Io,Rust,我想将泛型类型写入磁盘。比如: fn write_to_file<T: SomeTrait>(item: T, f: File) { f.write(item.to_bytes()); } fn写入文件(项目:T,f:文件){ f、 写入(item.to_bytes()); } 其中SomeTrait和to_字节组成。类型需要实现什么特性,如何将该类型的元素转换为可以写入编写器对象的形式 Encodable特性似乎很有希望,但我看到的唯一的Encoder是一个用于JSON

我想将泛型类型写入磁盘。比如:

fn write_to_file<T: SomeTrait>(item: T, f: File) {
    f.write(item.to_bytes());
}
fn写入文件(项目:T,f:文件){
f、 写入(item.to_bytes());
}
其中
SomeTrait
to_字节组成。类型需要实现什么特性,如何将该类型的元素转换为可以写入
编写器
对象的形式

Encodable
特性似乎很有希望,但我看到的唯一的
Encoder
是一个用于JSON的特性


编辑:我还在寻找一种从文件(或任何字节流)中读取泛型的方法,以防答案类似于写入。

一般来说,没有办法只将某个任意类型的值写入磁盘。您应该选择一些序列化策略,而一些适用于一种类型的策略不会适用于另一种类型

例如,您可以选择只写入结构内容的内存转储(使用一些不安全的转换):

不幸的是,我不知道如何排除带有
&'static
引用和原始poitner的结构。这两种类型的序列化和反序列化都是不安全的,但是似乎没有类型系统机制来排除它们

为了用指针序列化更复杂的结构,您需要一些特性,如
可编码
,它足够智能,可以支持任意类型。然而,仅仅是可编码是不够的,因为您仍然需要一些具体的序列化策略。例如,如何表示
Vec
?您不能只转储它的字节表示,所以您需要读取向量内容并以某种方式将它们存储到输出流中,可能是这样,以便以后可以反序列化它们。这就是为什么
可编码的
编码器
配对:
可编码的
实现“将其结构描述为
编码器
,编码器能够以某种格式将此结构存储到字节流中

因此,为了可靠地序列化某些类型,您至少需要为特定的序列化策略实现一个,并让您的类型实现
可编码的
(在大多数情况下,可以使用
#[派生(可编码)]
属性自动完成)。标准库中有一个
编码器的实现;如果知道序列化格式,可以使用
json::Encoder
作为参考实现

为了对某些类型进行反序列化,您需要为相同的序列化策略实现一个,并让您的类型实现
可解码
(同样,在大多数情况下,
#[派生(可解码)]
是自动的)。标准库中有一个解码器,它将实例转换为实现
Decodable
的类型值

请注意,
Json
编码和解码有些不对称。直接执行编码:
T:Encodable->byte data
,而解码是一个两步过程:
byte data->Json->T:Decodable
。这对于序列化策略可能是不必要的


有些库为各种序列化格式提供编码器,例如。你可以找到一个适合你需要的,或者自己写一些东西。

你最好是让这个特点,找一个
作者,按照自己的方式写。谢谢你的详细回答。出于我的需要,我认为
拷贝类型是完美的。谢谢请注意,它还高度依赖于平台(忘了在文本中提及)。例如,如果在64位系统上序列化一个结构,在32位系统上,由于
uint
/
int
大小差异(以及可能不同的结构布局),您的程序可能无法正确地对其进行反序列化。请注意,我更新了答案,除了
Copy
之外,还包括了
Send
。这是从允许的类型中排除引用所必需的。但它仍然不是完全安全的。。。
use std::mem;
use std::raw;
use std::io::IoResult;

fn dump<T, W: Writer>(item: &T, writer: &mut W) -> IoResult<()> {
    let slice: &[u8] = unsafe {
        mem::transmute(raw::Slice {
            data: item as *const _ as *const u8,
            len: mem::size_of::<T>()
        })
    };
    writer.write(slice)
}
struct SomeStruct {
    data: Vec<String>
}
fn dump<T: Copy+Send, W: Writer>(item: &T, writer: W) -> IoResult<()> { ... }