我一直把头撞在墙上,试图弄清楚如何管理同一较大切片的多个切片。我这样做的主要动机是,首先要有一个很大的切片,然后逐渐使用越来越小的子切片,直到该子切片仅包含一个元素。
从高层的角度来看,我不明白为什么不能做到这一点,因为我不需要移动或变异原始切片。我只需要切片的多个视图以及与原始切片相同的生存期。
为说明起见,请参考下图:
原始切片为绿色,向下的每一层代表越来越小的切片,直到切片中只有一个元素为止。我想要的是确保要“延伸”到原始切片的每个切片的元素的寿命,而不是取决于其上方的切片的寿命。我在while循环中使用这些切片,并将每个切片存储在队列中,该队列在循环期间一直持续。
我遇到的问题是切片没有“足够长的寿命”,尽管我不太清楚为什么会这样。
由于每个条带仅引用原始条带,是否有可能将这些条带存储为队列中的“拥有的条带”而不是新的矢量?性能上甚至有差异吗?将切片边界的索引存储在队列中以备后用会更好吗?感谢所有帮助,谢谢。
以下是一些精确地说明问题的代码:
pub struct Split<'a> {
pub first_half: &'a [&'a [u8]],
pub second_half: &'a [&'a [u8]],
}
impl<'a> Split<'a> {
pub fn new(first_half: &'a [&'a [u8]], second_half: &'a [&'a [u8]]) -> Split<'a> {
Self {
first_half,
second_half,
}
}
}
fn make_smaller_slice<'a>(slice: &'a [&'a [u8]]) -> Vec<&'a [u8]> {
let mut smaller_slice = Vec::with_capacity(slice.len());
for elem in slice {
if true {
smaller_slice.push(*elem)
}
}
smaller_slice
}
fn main() {
let mut original_data = Vec::with_capacity(100);
for i in 0..100 {
original_data.push(vec![i]);
}
let original_slice = original_data
.iter()
.map(|x| x.as_slice())
.collect::<Vec<_>>();
let mut split_queue = vec![];
split_queue.push(Split::new(&original_slice[0..50], &original_slice[50..100]));
loop {
let split = split_queue.remove(0);
let first_half = split.first_half.split_at(split.first_half.len() / 2);
let processed_first_half_0 = make_smaller_slice(&first_half.0);
let processed_first_half_1 = make_smaller_slice(&first_half.1);
let first_split = Split::new(&processed_first_half_0, &processed_first_half_1);
split_queue.insert(0, first_split);
}
}
以及由此产生的错误:
error[E0597]: `processed_first_half_0` does not live long enough
--> src/main.rs:44:38
|
38 | let split = split_queue.remove(0);
| ----------- borrow used here, in later iteration of loop
...
44 | let first_split = Split::new(&processed_first_half_0, &processed_first_half_1);
| ^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
45 | split_queue.insert(0, first_split);
46 | }
| - `processed_first_half_0` dropped here while still borrowed
error[E0597]: `processed_first_half_1` does not live long enough
--> src/main.rs:44:63
|
38 | let split = split_queue.remove(0);
| ----------- borrow used here, in later iteration of loop
...
44 | let first_split = Split::new(&processed_first_half_0, &processed_first_half_1);
| ^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
45 | split_queue.insert(0, first_split);
46 | }
| - `processed_first_half_1` dropped here while still borrowed
答案 0 :(得分:0)
修改make_smaller_slice
以返回对切片的引用而不是向量可以解决此问题。
pub struct Split<'a> {
pub first_half: &'a [&'a [u8]],
pub second_half: &'a [&'a [u8]]
}
impl<'a> Split<'a> {
pub fn new(first_half: &'a [&'a [u8]], second_half: &'a [&'a [u8]]) -> Split<'a> {
Self {
first_half,
second_half
}
}
}
fn make_smaller_slice<'a>(slice: &'a [&'a [u8]]) -> &'a[&'a [u8]] {
let mut start_bound = 0;
for i in 0..slice.len() {
if true {
start_bound = i;
}
}
&slice[start_bound..]
}
fn main() {
let mut original_data = Vec::with_capacity(100);
for i in 0..100 {
original_data.push(vec![i]);
}
let original_slice = original_data.iter().map(|x| x.as_slice()).collect::<Vec<_>>();
let mut split_queue = vec![];
split_queue.push(Split::new(&original_slice[0..50], &original_slice[50..100]));
loop {
let split = split_queue.remove(0);
let first_half = split.first_half.split_at(split.first_half.len() / 2);
let processed_first_half_0 = make_smaller_slice(&first_half.0);
let processed_first_half_1 = make_smaller_slice(&first_half.1);
let first_split = Split::new(&processed_first_half_0, &processed_first_half_1);
split_queue.insert(0, first_split);
}
}
为此,请从Reddit贷到_TheDust _。
答案 1 :(得分:0)
您的代码中存在潜在问题。在这两行中:
let split = split_queue.remove(0);
split_queue.insert(0, first_split);
这在时间上与split_queue
的长度成比例。您可能希望将Vec
替换为VecDeque
及其常量方法pop_front
和push_front
。