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

如何将Vec<Bytes>转换为Buf以用作Any::decode()的参数?

将Vec适配为Buf trait的实现方案

方案一:链式组合单个Bytes(适合少量元素)

单个Bytes已实现Buf trait,可通过Buf::chain方法将多个Bytes实例链接为一个逻辑上连续的Buf,全程无需复制内存:

use bytes::{Buf, Bytes};
use prost_types::Any;

let vec_bytes: Vec<Bytes> = /* 你的Vec<Bytes>实例 */;

// 处理空Vec的边界情况
let mut buf = vec_bytes.into_iter()
    .reduce(|acc, b| acc.chain(b))
    .unwrap_or_else(|| Bytes::new());

// 传入Any::decode
let any = Any::decode(&mut buf)?;

方案二:自定义适配器结构体(适合任意数量元素)

若Vec<Bytes>元素较多,链式调用会产生嵌套类型,可自定义适配器包装Vec<Bytes>并实现Buf trait:

use bytes::{Buf, Bytes};
use prost_types::Any;

// 自定义Buf适配器
struct VecBytesBuf {
    parts: Vec<Bytes>,
    current_idx: usize,
}

impl VecBytesBuf {
    fn new(parts: Vec<Bytes>) -> Self {
        Self {
            parts,
            current_idx: 0,
        }
    }
}

impl Buf for VecBytesBuf {
    fn remaining(&self) -> usize {
        self.parts[self.current_idx..]
            .iter()
            .map(|b| b.remaining())
            .sum()
    }

    fn chunk(&self) -> &[u8] {
        self.parts.get(self.current_idx)
            .map(Bytes::chunk)
            .unwrap_or(&[])
    }

    fn advance(&mut self, mut cnt: usize) {
        while cnt > 0 && self.current_idx < self.parts.len() {
            let current = &mut self.parts[self.current_idx];
            let take = cnt.min(current.remaining());
            current.advance(take);
            cnt -= take;
            if current.remaining() == 0 {
                self.current_idx += 1;
            }
        }
    }
}

// 使用示例
let vec_bytes: Vec<Bytes> = /* 你的Vec<Bytes>实例 */;
let mut buf = VecBytesBuf::new(vec_bytes);
let any = Any::decode(&mut buf)?;

关键说明

  • 两种方案均基于Bytes的零拷贝特性,全程无需复制内存,完全契合Buf trait的设计目标。
  • 自定义适配器仅实现了Buf的核心方法,足以满足Any::decode的调用需求(prost的解码逻辑仅依赖基础Buf操作)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 08:13:15