如何使用bincode序列化Rust枚举时忽略变体编码
解决bincode序列化枚举时的额外前缀问题
首先纠正一个误解:你看到的前8字节[2, 0, 0, 0, 0, 0, 0, 0]并不是枚举变体的编码,而是bincode默认序列化&[u8]时添加的u64长度前缀(因为你构建的buffer长度是2,这是小端字节序的u64值2)。你的自定义buffer是[1,97],加上这个长度前缀后就变成了10字节的结果。
要实现直接输出[1,97]的需求,有两种简洁的解决方案:
方案一:修改Serialize实现,避免额外长度前缀
不要先构建完整的buffer再调用serialize_bytes,而是直接使用序列化器的基础类型写入方法,分别输出长度字节和字符串内容:
#[derive(Debug)] enum Value { MyString(String), } impl serde::Serialize for Value { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, { match self { Value::MyString(s) => { let bytes = s.as_bytes(); // 创建序列化序列,指定总字节数 let mut seq = serializer.serialize_seq(Some(1 + bytes.len()))?; // 写入单字节长度 seq.serialize_element(&(bytes.len() as u8))?; // 逐个写入字符串的字节 for byte in bytes { seq.serialize_element(byte)?; } seq.end() } } } }
这样序列化时会直接输出长度字节和字符串的所有字节,不会产生额外前缀。
方案二:保留原有Serialize实现,修改bincode配置
如果你想保留自己构建buffer的逻辑,可以修改bincode的序列化配置,禁用字节数组的长度前缀:
fn main() { let value = Value::MyString("a".into()); let encoded = bincode::options() .with_no_length_prefix() // 禁用字节数组的长度前缀 .serialize(&value) .unwrap(); println!("{encoded:?}"); // 输出 [1, 97] }
这个配置会让bincode序列化&[u8]时直接输出字节内容,不再添加长度前缀,正好符合你的需求。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

