Serialization 围绕固定大小向量实现包装器的可解码
背景:序列化板条箱未记录,派生可解码文件不起作用。我还研究了其他类型的现有实现,发现代码很难遵循 解码过程是如何工作的,我如何为这个结构实现可解码的Serialization 围绕固定大小向量实现包装器的可解码,serialization,rust,Serialization,Rust,背景:序列化板条箱未记录,派生可解码文件不起作用。我还研究了其他类型的现有实现,发现代码很难遵循 解码过程是如何工作的,我如何为这个结构实现可解码的 pub struct Grid<A> { data: [[A,..GRIDW],..GRIDH] } 在Decodable::decode(d) 错误:未能找到trait的实现 serialize::serialize::可解码的[[A,…20],…20] 由于各种原因,目前不可能很好地做到这一点: 我们不能在固定长度数组的
pub struct Grid<A> {
data: [[A,..GRIDW],..GRIDH]
}
在Decodable::decode(d)
错误:未能找到trait的实现
serialize::serialize::可解码的[[A,…20],…20]
由于各种原因,目前不可能很好地做到这一点:
- 我们不能在固定长度数组的长度上通用(基本问题)
- 当前的trait一致性限制意味着我们不能用[a,…GRIDW](还有一个用于
)的GRIDH
impl-MyDecodable来编写自定义
)和一个整体实现trait-MyDecodable{…}
impl 通过使用来实例化每个版本,还可以编写一个更“通用”的
解码器,并对递归解码的处理方式进行特殊控制,以允许处理嵌套的固定长度数组(如[T,…n]
网格所需);这需要更少的代码(尤其是具有更多层或各种不同长度的代码),但宏解决方案:
- 可能更难理解,而且
- 我给出的方法可能效率较低(为每个固定长度数组创建了一个新的
变量,包括新的array
s,而上面的非宏解决方案只使用一个Default
,因此对网格中的每个元素只调用一次array
)。可以扩展到一组类似的递归循环,但我不确定Default::Default
--非常扩展的
获得该定义,然后进行调整以适应新形式”。@ChrisMorgan我根本不知道如何将其调整为新形式。@A.B.您试图反序列化的JSON字符串是什么?-下面是几个JSON反序列化的例子。这能处理JSON吗?这可能是一个愚蠢的问题,但JSON不需要在尝试读取序列之前读取结构名称和数据字段吗?@a.B.噢,哎呀;我已经计划好了(为什么我有一个单独的函数),但是忘记了正确地实现它。现在修好了。
impl <A: Decodable<D, E>, D: Decoder<E>, E> Decodable<D, E> for Grid<A> { fn decode(decoder: &mut D) -> Result<Grid<A>, E> { decoder.read_struct("Grid", 1u, ref |d| Ok(Grid { data: match d.read_struct_field("data", 0u, ref |d| Decodable::decode(d)) { Ok(e) => e, Err(e) => return Err(e) }, })) } }
extern crate serialize; use std::default::Default; use serialize::{Decoder, Decodable}; static GRIDW: uint = 10; static GRIDH: uint = 5; fn decode_grid<E, D: Decoder<E>, A: Copy + Default + Decodable<D, E>>(d: &mut D) -> Result<Grid<A>, E> { // mirror the Vec implementation: try to read a sequence d.read_seq(|d, len| { // check it's the required length if len != GRIDH { return Err( d.error(format!("expecting length {} but found {}", GRIDH, len).as_slice())); } // create the array with empty values ... let mut array: [[A, .. GRIDW], .. GRIDH] = [[Default::default(), .. GRIDW], .. GRIDH]; // ... and fill it in progressively ... for (i, outer) in array.mut_iter().enumerate() { // ... by reading each outer element ... try!(d.read_seq_elt(i, |d| { // ... as a sequence ... d.read_seq(|d, len| { // ... of the right length, if len != GRIDW { return Err(d.error("...")) } // and then read each element of that sequence as the // elements of the grid. for (j, inner) in outer.mut_iter().enumerate() { *inner = try!(d.read_seq_elt(j, Decodable::decode)); } Ok(()) }) })); } // all done successfully! Ok(Grid { data: array }) }) } pub struct Grid<A> { data: [[A,..GRIDW],..GRIDH] } impl<E, D: Decoder<E>, A: Copy + Default + Decodable<D, E>> Decodable<D, E> for Grid<A> { fn decode(d: &mut D) -> Result<Grid<A>, E> { d.read_struct("Grid", 1, |d| { d.read_struct_field("data", 0, decode_grid) }) } } fn main() {}