使用serde序列化嵌套对象数组:基于Grid结构体生成目标JSON的实现问题
Rust Grid结构体自定义序列化嵌套数组方案
问题根源
你代码里的核心错误有两个:
SerializeSeqtrait 仅提供serialize_element、end方法,不存在serialize_seq方法,无法直接在外层序列实例上创建内层嵌套序列- 单元格索引计算逻辑错误:你使用
column_index * self.height + row_index计算一维偏移,仅在正方形网格下刚好生效,非正方形网格会得到错误的单元格下标,正确计算方式为行索引 * 每行宽度(width) + 列索引
最优实现方案
最容易维护且不易出错的方式是先将Grid的一维字段转换为嵌套的单元格集合,直接序列化该集合即可得到目标结构,无需手动处理嵌套序列化的层级逻辑:
步骤1:定义单元格结构体
use serde::Serialize; #[derive(Serialize)] struct Cell { display: char, solution: char, } // 原Grid结构体 struct Grid { display: String, solution: String, width: usize, height: usize, }
步骤2:实现Grid的Serialize trait
impl Serialize for Grid { fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { let mut grid_rows = Vec::with_capacity(self.height); // 遍历每一行 for row_idx in 0..self.height { let mut row_cells = Vec::with_capacity(self.width); // 遍历当前行每一列 for col_idx in 0..self.width { // 计算一维字符串中的正确偏移 let cell_idx = row_idx * self.width + col_idx; row_cells.push(Cell { display: self.display.chars().nth(cell_idx).unwrap(), solution: self.solution.chars().nth(cell_idx).unwrap(), }); } grid_rows.push(row_cells); } // 直接序列化嵌套Vec,自动生成目标嵌套数组结构 grid_rows.serialize(serializer) } }
零额外结构体实现方案
如果你不想额外定义Cell结构体,可以通过手动调用内层序列化接口实现,避免额外的结构定义:
use serde::{Serialize, Serializer, ser::SerializeSeq, ser::SerializeMap}; impl Serialize for Grid { fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { let mut outer_seq = serializer.serialize_seq(Some(self.height))?; for row_idx in 0..self.height { // 为每一行实现序列化逻辑,作为外层序列的元素 outer_seq.serialize_element(&serde::ser::Serialize::serialize( &(), |inner_ser| { let mut inner_seq = inner_ser.serialize_seq(Some(self.width))?; for col_idx in 0..self.width { let cell_idx = row_idx * self.width + col_idx; // 为每个单元格实现序列化逻辑,作为内层序列的元素 inner_seq.serialize_element(&serde::ser::Serialize::serialize( &(), |cell_ser| { let mut map = cell_ser.serialize_map(Some(2))?; map.serialize_entry("display", &self.display.chars().nth(cell_idx).unwrap())?; map.serialize_entry("solution", &self.solution.chars().nth(cell_idx).unwrap())?; map.end() } ))?; } inner_seq.end() } ))?; } outer_seq.end() } }
内容的提问来源于stack exchange,提问作者River Tam
相关产品推荐
相关产品推荐

