gpt4 book ai didi

rust - 管理同一内存段的多个切片

转载 作者:行者123 更新时间:2023-11-29 08:34:07 25 4
gpt4 key购买 nike

我一直在用头撞墙试图弄清楚如何管理同一个较大切片的多个切片。我这样做的主要动机是我从一些大切片开始,然后逐渐处理越来越小的子切片,直到子切片只包含一个元素。

从高层次的角度来看,我不清楚为什么不能这样做,因为我不需要移动或改变原始切片。我只需要与原始切片具有相同生命周期的切片的多个 View 。

为了说明,请引用此图:

Memory Model

原始切片是绿色的,往下每一层表示尺寸越来越小的切片,直到切片中只有一个元素。我想要的是确保每个切片的元素的生命周期“到达”原始切片,而不依赖于它上面的切片的生命周期。我在一个 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

最佳答案

修改 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_。

关于rust - 管理同一内存段的多个切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54968221/

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