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

ua4mk5z4  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(58)

实际问题(避免A/B场景):
我在Arc对象后面有一个很大的缓冲区:

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

字符串
我需要将Read + Seek版本作为函数的Box'ed返回值传递给网络API(不复制整个缓冲区)。
首先,我试着让Cursor引用Vec:

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


但是编译器正确地警告这个游标实际上可能比所有ARC示例都存在。
我的第二个想法是将CursorArc打包到新的结构中,并为其实现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()会复制vector,这是我想要避免的。
这是我放弃的地方。
我在这里错过了什么吗?我如何从Arc<Vec<u8>>创建Read + Seek对象?

j91ykkif

j91ykkif1#

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>>提取到不同的结构中。

相关问题