gpt4 book ai didi

generics - Rust:泛型必须实现 &xx[...]

转载 作者:行者123 更新时间:2023-12-03 11:44:08 25 4
gpt4 key购买 nike

我正在尝试实现一个通用结构,从一开始就很清楚它的元素“提供者”必须是稍后支持 &myvar.provider[..] 的类型。但我无法为此计算出正确的界限。

pub struct MyStruct<T: ??> {  // T must support &x.provider[..]
pub provider: T,
}
非常感谢你的帮助
更新:扩展示例。我想要实现的目标:数据 block 最大可达 10GB。它们可以作为静态 b"aa"提供,主要用于测试、将文件内容读入内存或映射文件内容。无论提供者如何,在处理数据时我们只使用 &[u8]。
//
// A minimal example for my problem
//

use std::str;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::boxed::Box;
use memmap::{MmapOptions, Mmap};

#[derive(Debug)]
pub struct DBFileBuilder<T> { // what is the correct bound? T must support &x[..]
pub filename: String,
pub provider: Option<T>,
pub startpos: usize,
// ... several more
}

pub struct DBFile<'a, T> { // what is the correct bound? T must support &x[..]
pub filename: String,
pub provider: T,
pub data: &'a [u8],
// ... several more
}

impl<T> DBFileBuilder<T> {
fn default() -> Self {
Self {
filename: String::default(),
provider: None,
startpos: 0,
}
}

pub fn from_bytes(data: &[u8]) -> DBFileBuilder<&[u8]> {
DBFileBuilder {
provider: Some(&data),
..DBFileBuilder::default()
}
}

pub fn read_file(filename: &str) -> Result<DBFileBuilder<Box<[u8]>>, Box<dyn Error>> {
let mut file = File::open(&filename)?;
let fsize = file.metadata()?.len();

let mut provider = vec![0_u8; fsize as usize].into_boxed_slice();
let n = file.read(&mut provider)?;

Ok(DBFileBuilder {
filename: filename.to_string(),
provider: Some(provider),
..DBFileBuilder::default()
})
}

pub fn mmap_file(filename: &str) -> Result<DBFileBuilder<Mmap>, Box<dyn Error>> {
let file = File::open(&filename)?;
let provider = unsafe { MmapOptions::new().map(&file)? };

Ok(DBFileBuilder {
filename: filename.to_string(),
provider: Some(provider),
..DBFileBuilder::default()
})
}

pub fn init(&mut self) {
}

pub fn build<'a>(self) -> DBFile<'a, T> {
let provider = self.provider.expect("Provider not initialized");
self.init();
let data = &provider[self.startpos ..];

DBFile {
filename: self.filename,
provider,
data,
}
}
}

impl<'a, T> DBFile<'a, T> {
pub fn run(&self) {
return self.process(self.data)
}

pub fn process(&self, data: &[u8]) {
println!("data: {:?}", &data);
}
}

最佳答案

通过使用封闭范围来获取字节绑定(bind)到索引的必要特征是 Index<Range<usize>, Output=[u8]> .
您可能还想按无限范围索引:

pub struct MyStruct<T>
where T: Index<Range<usize>, Output=[u8]>
+ Index<RangeTo<usize>, Output=[u8]>
+ Index<RangeFrom<usize>, Output=[u8]>
+ Index<RangeFull, Output=[u8]>
{
pub provider: T,
}
不幸的是,这些界限目前没有在 MyStruct 的签名中推断出来。被使用(尽管我相信这是在工作中),这可能会变得非常笨拙。如果你使用 Nightly,你可以定义一个 trait alias (RFC1733)以减少冗长。
也就是说,您需要重新考虑该示例,因为它不起作用:例如在 build() data不能是返回的 DBFile 的一部分因为它指向一个生命周期不够长的局部变量。

关于generics - Rust:泛型必须实现 &xx[...],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65853124/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com