【发布时间】:2020-12-18 20:39:41
【问题描述】:
在以下 rust 示例中,Values 结构包含值列表,Refs 结构包含对这些值的一些引用。此代码产生编译器错误,显示在帖子底部,表明generate_ref 中self.values 的生命周期本质上必须为'a,因此即使引用用于生成@,也无法生成ref2 987654329@ 在它自己的代码块中。
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),但每个频道只有一个广播者。
【问题讨论】:
-
您能解释一下为什么在一个结构中需要 2 个可变 i32 引用以及您打算如何使用它们吗?
-
您不能在持有对其元素之一的引用时修改矢量。尝试这样做是不合理的,因为将新元素附加到向量可能会重新分配向量,从而使所有现有引用无效。
-
正如@pretzelhammer 所说,目的是什么,因为这改变了方法。您可以像实现图形结构一样实现它,即使用
Rc或返回Id。见“Implement graph-like datastructure in Rust” -
@pretzelhammer 这是一个简化的例子。真正的代码引用了两个更复杂的结构。此外,
Vec与 HashMap 一样,但我怀疑它会遇到@Sven Marnach 提到的相同问题。 -
@mentoc3000 如果是这种情况,那么我认为您将示例过度简化到了我们无法为您提供有意义帮助的地步。请更新您的问题以显示更符合您的实际用例的代码。