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

Rust无内存分配场景下多次write_all后获取实际输出的优雅方案

Rust 缓冲区写入后获取有效数据的优雅方案

问题现象

以下代码运行后打印结果为[0, 0, 0, 0, 0],无法得到实际写入的有效数据:

use std::io::Write;

pub struct A{
    pub a: u8,
    pub b: u16
}

impl A {
    pub fn to_bytes(&self, output: &mut &mut[u8]) -> Result<(), std::io::Error> {
        output.write_all(&[self.a])?;
        output.write_all(&self.b.to_be_bytes()[..])?;
        Ok(())
    }
}

fn main() {
    let mut buffer: &mut [u8] = &mut [0u8; 10];
    let a = A{
        a: 7,
        b: 100
    };
    a.to_bytes(&mut buffer);
    println!("{:?}", buffer);
}

问题原因

当使用&mut &mut [u8]作为Write的目标时,每次调用write_all后,切片会自动调整为指向剩余未写入的区域。因此最终buffer指向的是从未被写入的部分,自然全为0。

需求限制

  • 禁止手动跟踪写入字节数来截取子切片
  • 运行环境为微控制器,不允许内存分配,只能传入最坏情况大小的缓冲区,且缓冲区几乎不会被写满

解决方案

使用标准库的std::io::Cursor包装原始缓冲区,它会自动跟踪写入位置,且完全不分配额外内存。之后通过Cursor的position()方法获取写入字节数,再对原始缓冲区进行切片即可:

use std::io::{Write, Cursor};

pub struct A{
    pub a: u8,
    pub b: u16
}

impl A {
    pub fn to_bytes(&self, output: &mut Cursor<&mut [u8]>) -> Result<(), std::io::Error> {
        output.write_all(&[self.a])?;
        output.write_all(&self.b.to_be_bytes()[..])?;
        Ok(())
    }
}

fn main() {
    let mut buffer = [0u8; 10];
    let mut cursor = Cursor::new(&mut buffer);
    let a = A{
        a: 7,
        b: 100
    };
    
    // 实际项目中建议处理错误,此处为简化示例忽略
    let _ = a.to_bytes(&mut cursor);
    
    // 获取有效数据切片
    let written_len = cursor.position() as usize;
    let valid_data = &buffer[..written_len];
    println!("{:?}", valid_data); // 输出: [7, 0, 100]
}

方案优势

  • 无需手动计算写入字节数,Cursor自动维护写入位置
  • 零内存分配,完全适配微控制器的资源限制
  • 基于标准库实现,代码简洁易维护,无需自定义复杂逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 21:53:13