gpt4 book ai didi

rust - 对存储在向量中的值的引用的生命周期

转载 作者:行者123 更新时间:2023-12-03 11:47:07 24 4
gpt4 key购买 nike

在以下 rust 示例中,Values结构包含一个值列表和一个 Refs结构包含对这些值的一些引用。此代码产生编译器错误,显示在帖子底部,表明在 generate_refself.values本质上必须有 'a 的生命周期,导致无法生成 ref2即使用于生成 ref1 的引用在它自己的代码块中。

pub struct Values {
values: Vec<i32>,
}

impl<'a> Values {
pub fn new() -> Values {
Values { values: vec![] }
}

pub fn generate_ref(&mut self) -> &'a mut i32 {
self.values.push(1);
self.values.last_mut().unwrap()
}
}

pub struct Refs<'a> {
ref1: &'a mut i32,
ref2: &'a mut i32,
}

impl<'a> Refs<'a> {
pub fn new(values: &'a mut Values) -> Refs {
let ref1 = { values.generate_ref() };
let ref2 = { values.generate_ref() };
Refs { ref1, ref2 }
}
}

fn main() {
let mut values = Values::new();
let refs = Refs::new(&mut values);
let ref3 = { values.generate_ref() };
}
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src\main.rs:12:9
|
12 | self.values.last_mut().unwrap()
| ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 10:5...
--> src\main.rs:10:5
|
10 | / pub fn generate_ref(&mut self) -> &'a mut i32 {
11 | | self.values.push(1);
12 | | self.values.last_mut().unwrap()
13 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src\main.rs:12:9
|
12 | self.values.last_mut().unwrap()
| ^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 5:6...
--> src\main.rs:5:6
|
5 | impl<'a> Values {
| ^^
note: ...so that reference does not outlive borrowed content
--> src\main.rs:12:9
|
12 | self.values.last_mut().unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我真正需要的是确保从 generate_ref 返回的引用持续时间与存储在 Values 中的值一样长.我怎样才能做到这一点?如果这是不可能的,是否有另一种方法来构建在 Rust 中有效的代码?
编辑
有关更多上下文,这是一个简化的示例。在实际实现中, Values持有 bus::Bus 向接收者广播数据。接收器由 Bus 生产。 .各种其他结构包含接收器( bus::BusReader)和对广播者的引用( &mut bus::Bus),但每个 channel 只有一个广播者。

最佳答案

虽然可以将多个可变引用返回到 Vec使用 split_at_mut 等方法它的可扩展性不是很高,而且很少值得麻烦。推荐的解决方案是通过索引而不是通过引用来引用元素,这会从您的代码中删除所有生命周期,并使其更加简单和易于管理:

pub struct Values {
values: Vec<i32>,
}

impl Values {
pub fn new() -> Values {
Values { values: vec![] }
}

pub fn generate_index(&mut self) -> usize {
self.values.push(1);
self.values.len() - 1
}
}

pub struct Indices {
idx1: usize,
idx2: usize,
}

impl Indices {
pub fn new(values: &mut Values) -> Self {
Indices {
idx1: values.generate_index(),
idx2: values.generate_index(),
}
}
}

fn main() {
let mut values = Values::new();
let indicies = Indices::new(&mut values);
let idx3 = values.generate_index();
}
上述方法的一个缺点是您永远无法从 Vec 中删除元素。因为这会改变所有的索引,但是这个问题可以通过使用像 generational_arena 这样的 crate 来解决。这就像 Vec但它返回有效的索引,即使元素被删除也仍然存在。

关于rust - 对存储在向量中的值的引用的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65363640/

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