我正在努力从mylist
中获取一个具有生命周期参考的元素。我把我的代码简化为:
Vec
产生此错误:
pub trait Runnable {}
pub struct RunList<'a> {
runnables: Vec<&'a mut Runnable>,
}
impl<'a> RunList<'a> {
pub fn get(&self, id: usize) -> &'a mut Runnable {
self.runnables[id]
}
}
fn main() {}
答案 0 :(得分:3)
首先,从'a
的返回值类型中删除生命周期参数get
:
pub trait Runnable {}
pub struct RunList<'a> {
runnables: Vec<&'a mut Runnable>,
}
impl<'a> RunList<'a> {
pub fn get(&mut self, id: usize) -> &mut Runnable {
self.runnables[id]
}
}
fn main() {}
这可以解决潜在的问题:
error[E0389]: cannot borrow data mutably in a `&` reference
--> src/main.rs:9:9
|
9 | self.runnables[id]
| ^^^^^^^^^^^^^^^^^^ assignment into an immutable reference
self.runnables[id]
不可侵犯地借用&'a mut Runnable
并隐含地取消引用它。你无法将&'a mut Runnable
移出这个不可变借入。相反,你可以重新延长可运行的东西,这需要可变借用self
:
impl<'a> RunList<'a> {
pub fn get(&mut self, id: usize) -> &mut Runnable {
&mut *self.runnables[id]
}
}
要了解这里究竟发生了什么,应该阅读:What is the return type of the indexing operation?
pub fn get(&mut self, id: usize) -> &mut Runnable {
self.runnables[id]
}
相当于:
pub fn get(&mut self, id: usize) -> &mut Runnable {
let r: &&mut (Runnable + 'a) = self.runnables.index(id);
*r
}
index
返回&'a mut Runnable
的不可变引用,其类型为&&mut (Runnable + 'a)
。返回*r
不起作用,因为您无法从借用内容中移动可变引用 1 ,并且不可变地借用不可变引用中的数据({{1} }不起作用)。因此,您需要&mut**r
的版本,该版本授予对索引元素的可变访问权:index
index_mut
这很有效,因为pub fn get(&mut self, id: usize) -> &mut Runnable {
let r: &mut &'a mut (Runnable + 'a) = self.runnables.index_mut(id);
*r
}
实际上可以在*r
内部重新插入Runnable
。与上面使用不可变引用&mut**r
的情况相反,可变地引用可变引用r
内的数据是完全正确的。执行r
时,参数&mut**r
会在解除引用过程中丢失。因此,返回'a
而不是&'a mut Runnable
在此处不起作用。
最后,&mut Runnable
告诉编译器隐式解析为&mut *self.runnables[id]
而不是*self.runnables.index_mut(id)
。 *self.runnables.index(id)
也可以。
1 可变引用不是*&mut self.runnables[id]
。如果您将代码中的所有Copy
更改为&'a mut Runnable
,则会进行编译,因为不可变引用为&'a Runnable