如何在 Rust 中通过 Arc<Vec> 创建 Cursor(或其他 Read + Seek 对象)?

问题描述 投票:0回答:1

实际问题(避免 A/B 场景):

我在 Arc 对象后面有一个很大的缓冲区:

pub struct LargeData {
    data: Arc<Vec<u8>>,
}

我需要将

Read + Seek
版本传递给网络 API 作为 Box'ed 从函数返回(不复制整个缓冲区)。

首先,我尝试将光标设置为对 Vec 的引用:

fn open_for_read(&self) -> io::Result<Box<dyn ReadAndSeek>> {
    Ok(Box::new(Cursor::new(self.data.as_ref())))
}

但是编译器正确地警告了该游标实际上可能比所有 ARC 实例的寿命都长。

我的第二个想法是将

Cursor
Arc
打包到新结构中并为其实现
Read + Seek


struct ReaderData {
    data: Arc<Vec<u8>>,
    cursor: Cursor<Vec<u8>>,
}

impl ReaderData {
    fn new(source: &LargeData) -> Self {
        let data = source.data.clone();
        Self {
            data,
            cursor: Cursor::new(data),
        }
    }
}
// Read + Seek implementation that only passes into cursor Read and Seek 

但是这次我遇到了更神秘的错误:

cursor: Cursor::new(data),
        ----------- ^^^^- help: try using a conversion method: `.to_vec()`
        |           |
        |           expected `Vec<u8>`, found `Arc<Vec<u8>>`
        arguments to this function are incorrect

使用

to_vec()
会复制向量,这是我想避免的。

这是我放弃的地方。

我在这里遗漏了什么吗?我如何从

Read + Seek
制作
Arc<Vec<u8>>
对象?

rust stream iterator
1个回答
0
投票

Cursor
需要实现
AsRef<[u8]>
的类型。
Arc<Vec<u8>>
不幸的是没有,但你可以自己实现
LargeData

#[derive(Clone)]
pub struct LargeData {
    data: Arc<Vec<u8>>,
}

impl AsRef<[u8]> for LargeData {
    fn as_ref(&self) -> &[u8] {
        &self.data
    }
}

impl LargeData {
    fn open_for_read(&self) -> Cursor<LargeData> {
        Cursor::new(self.clone())
    }
}

如果

LargeData
包含其他字段,您可以将
Arc<Vec<u8>>
提取到不同的结构体。

© www.soinside.com 2019 - 2024. All rights reserved.