You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JSON数组反序列化至已创建的Rust Vec以实现复用?

将JSON反序列化至现有Vec的解决方案

serde_json没有直接提供from_str_into这类直接写入现有Vec的API,但可以通过以下两种方式实现内存复用:

方案一:自定义Visitor实现

通过实现serde的Visitor trait,持有目标Vec的可变引用,在反序列化数组时直接将元素写入已有Vec:

use serde::{de::Visitor, Deserialize, Deserializer};
use serde_json;
use std::fmt;

fn request(i: usize) -> String {
    let mut v = vec![0; i];
    for n in 1..i {
        v[n] = n as i32;
    }
    serde_json::to_string(&v).unwrap()
}

struct VecVisitor<'a, T: Deserialize<'a>> {
    target: &'a mut Vec<T>,
}

impl<'a, T: Deserialize<'a>> Visitor<'a> for VecVisitor<'a, T> {
    type Value = ();

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("a JSON array")
    }

    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
    where
        A: serde::de::SeqAccess<'a>,
    {
        self.target.clear();
        // 预分配容量优化性能(可选)
        if let Some(len) = seq.size_hint() {
            self.target.reserve(len);
        }
        while let Some(element) = seq.next_element()? {
            self.target.push(element);
        }
        Ok(())
    }
}

fn deserialize_into_vec<'a, T: Deserialize<'a>>(json: &'a str, target: &mut Vec<T>) -> Result<(), serde_json::Error> {
    let deserializer = serde_json::Deserializer::from_str(json);
    let visitor = VecVisitor { target };
    deserializer.deserialize_seq(visitor)
}

fn main() {
    let mut bigvec = serde_json::from_str::<Vec<i32>>(&request(100)).unwrap();
    println!("{:?}", &bigvec);

    let many_iterations = 10;
    for n in 1..many_iterations {
        let resp = request(n);
        deserialize_into_vec(&resp, &mut bigvec).unwrap();
        println!("Iteration {}: len = {}", n, bigvec.len());
    }
}

方案二:流式反序列化简化实现

利用serde_json的StreamDeserializer逐个解析数组元素,直接写入现有Vec,无需自定义Visitor:

use serde_json::{self, Deserializer};
use serde::Deserialize;

fn request(i: usize) -> String {
    let mut v = vec![0; i];
    for n in 1..i {
        v[n] = n as i32;
    }
    serde_json::to_string(&v).unwrap()
}

fn deserialize_into_vec<T: for<'a> Deserialize<'a>>(json: &str, target: &mut Vec<T>) -> Result<(), serde_json::Error> {
    target.clear();
    let deserializer = Deserializer::from_str(json);
    let mut stream = deserializer.into_iter::<T>();
    while let Some(item) = stream.next() {
        target.push(item?);
    }
    Ok(())
}

fn main() {
    let mut bigvec = serde_json::from_str::<Vec<i32>>(&request(100)).unwrap();
    println!("{:?}", &bigvec);

    let many_iterations = 10;
    for n in 1..many_iterations {
        let resp = request(n);
        deserialize_into_vec(&resp, &mut bigvec).unwrap();
        println!("Iteration {}: len = {}", n, bigvec.len());
    }
}

核心要点

  • 两种方案都会先调用target.clear()清空Vec,再写入新元素,完全复用原有内存空间。
  • 方案一中的reserve(len)可选,用于根据序列预估长度预分配内存,减少动态扩容开销。
  • 方案二代码更简洁,无需手动实现Visitor,适合大多数常规场景。

内容的提问来源于stack exchange,提问作者fvall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:31:00