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
相关产品推荐
相关产品推荐

