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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:59:54