Serde使用serialize_seq序列化预先长度未知序列的实现方法
问题解答
核心误区说明
你给出的示例写法存在两个关键错误:
serialize_seq的入参是调用时就会被序列化器读取的提示值,后续修改lazy_len变量完全不会影响已经传入的数值,你一开始传入Some(0)等于告知序列化器该序列长度为0,后续添加元素会不符合序列化约定直接出错。- 你示例中
let mut lazy_len = 0末尾缺少分号,无法通过编译。
未知长度序列的正确实现
要适配遍历前无法计算长度的场景,直接给serialize_seq传入None即可:该参数是Option<usize>类型,None就代表序列长度未知。
如果你需要最终输出的序列长度是原序列的2倍,示例代码如下:
use serde::ser::{Serialize, Serializer, SerializeSeq}; impl<T> Serialize for Vec<T> where T: Serialize, { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { // 传None表示序列长度未知 let mut seq = serializer.serialize_seq(None)?; for element in self { // 每个原元素对应输出两个元素,总长度为原序列的2倍 seq.serialize_element(element)?; seq.serialize_element(element)?; } seq.end() } }
注意事项
- 不是所有序列化器都支持未知长度序列:例如bincode这类需要提前写入长度前缀的二进制序列化格式,遇到
serialize_seq(None)会直接返回错误;只有JSON这类本身不需要预先声明序列长度的格式可以正常运行。 - 若能提前计算出序列长度,尽量传入
Some(长度),兼容性更好,序列化性能也更高。
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

