我正在尝试将一些C++代码移植到Rust.它由几种切片(字符串引用,延迟评估的字符串引用,物理文件的一部分)组成虚拟(.mp4)文件,并根据结果提供HTTP请求.(如果你很好奇,看看Mp4File更是把优势FileSlice接口及其具体实现在http.h.)
这是问题:我想要尽可能少的堆分配.假设我有一些实现resource::Slice,我希望能够自己解决这个问题.然后我想制作一个组成它们的那个:
pub trait Slice : Send + Sync {
/// Returns the length of the slice in bytes.
fn len(&self) -> u64;
/// Writes bytes indicated by `range` to `out.`
fn write_to(&self, range: &ByteRange,
out: &mut io::Write) -> io::Result<()>;
}
// (used below)
struct SliceInfo<'a> {
range: ByteRange,
slice: &'a Slice,
}
/// A `Slice` composed of other `Slice`s.
pub struct Slices<'a> {
len: u64,
slices: Vec<SliceInfo<'a>>,
}
impl<'a> Slices<'a> {
pub fn new() -> Slices<'a> { ... }
pub fn append(&mut self, slice: &'a resource::Slice) { ... }
}
impl<'a> Slice for Slices<'a> { ... }
Run Code Online (Sandbox Code Playgroud)
并使用它们以尽可能少的堆分配附加大量和大量的切片.简化,像这样:
struct ThingUsedWithinMp4Resource {
slice_a: resource::LazySlice,
slice_b: resource::LazySlice,
slice_c: resource::LazySlice,
slice_d: resource::FileSlice,
}
struct Mp4Resource {
slice_a: resource::StringSlice,
slice_b: resource::LazySlice,
slice_c: resource::StringSlice,
slice_d: resource::LazySlice,
things: Vec<ThingUsedWithinMp4Resource>,
slices: resource::Slices
}
impl Mp4Resource {
fn new() {
let mut f = Mp4Resource{slice_a: ...,
slice_b: ...,
slice_c: ...,
slices: resource::Slices::new()};
// ...fill `things` with hundreds of things...
slices.append(&f.slice_a);
for thing in f.things { slices.append(&thing.slice_a); }
slices.append(&f.slice_b);
for thing in f.things { slices.append(&thing.slice_b); }
slices.append(&f.slice_c);
for thing in f.things { slices.append(&thing.slice_c); }
slices.append(&f.slice_d);
for thing in f.things { slices.append(&thing.slice_d); }
f;
}
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用.附加行会导致错误"f.slice_*活得不够长","引用必须对生命周期内的a有效'a在块上定义...","...但借用的值仅对于块后缀以下语句".我认为这与关于自引用结构的这个问题类似.这基本上是这样的,具有更多的间接性.而且显然这是不可能的.
那么我该怎么做呢?
我想我很乐意给予resource::Slicesin in append,但是我不能把resource::Slice它SliceInfo用在in中,Vec<SliceInfo>因为它resource::Slice是一种特性,而且特征是不合格的.我可以Box<resource::Slice>改为做,但这意味着为每个切片分别进行堆分配.我想避免这种情况.(每个Mp4Resource可以有数千个切片.)
我正在考虑做一个枚举,比如:
enum BasicSlice {
String(StringSlice),
Lazy(LazySlice),
File(FileSlice)
};
Run Code Online (Sandbox Code Playgroud)
并在中使用它SliceInfo.我想我可以做到这一点.但它绝对限制了我resource::Slices班级的实用性.我希望允许它在我没有预料到的情况下轻松使用,最好不必每次都定义一个新的枚举.
还有其他选择吗?
| 归档时间: |
|
| 查看次数: |
183 次 |
| 最近记录: |