我几天前开始编写Rust代码,刚刚第一次遇到借用检查程序。
#[derive(Clone, Eq, Debug, PartialEq)]
pub struct Vm<'a> {
instructions: Rc<InstructionSequence>,
pc: usize,
stack: Vec<Value<'a>>,
frames: Vec<Frame<'a>>,
}
impl<'a> Vm<'a> {
pub fn run(&'a mut self) {
loop {
let instruction = self.instructions.get(self.pc).unwrap();
match instruction {
&Instruction::Push(ref value) => {
let top_activation = &mut self.frames.last_mut().unwrap().activation;
self.stack.push(Vm::literal_to_value(value, top_activation))
},
_ => ()
};
};
}
}
Rust给了我以下错误:
error[E0499]: cannot borrow `self.frames` as mutable more than once at a time
--> src/vm.rs:157:47
|
157 | let top_activation = &mut self.frames.last_mut().unwrap().activation;
| ^^^^^^^^^^^
| |
| second mutable borrow occurs here
| first mutable borrow occurs here
...
181 | }
| - first borrow ends here
error[E0499]: cannot borrow `self.frames` as mutable more than once at a time
--> src/vm.rs:157:47
|
157 | let top_activation = &mut self.frames.last_mut().unwrap().activation;
| ^^^^^^^^^^^
| |
| second mutable borrow occurs here
| first mutable borrow occurs here
...
181 | }
| - first borrow ends here
error: aborting due to 2 previous errors
我不明白为什么要借两次。发生了什么事?
答案 0 :(得分:1)
您在堆栈上推送的值会在self.frames
处于活动状态时保持可变借位。在第二次循环迭代中,该借用仍处于活动状态,因此您无法在self.frames
上进行第二次借用。
Vm::literal_to_value
不需要对激活对象进行可变引用,因此您可以更改代码以获取不可变引用:
match instruction {
&Instruction::Push(ref value) => {
let top_activation = &self.frames.last().unwrap().activation;
self.stack.push(Vm::literal_to_value(value, top_activation))
},
_ => ()
};
这会使run
编译,但是你的测试无法编译。那是因为有了这个签名:
pub fn run(&'a mut self)
您将self
的生命周期与Vm
上的生命周期参数相关联。从本质上讲,此处self
的类型为&'a mut Vm<'a>
; 'a
在这里出现两次的事实,再加上它是一个可变的借用(而不是一个不可变的借用)这一事实告诉Rust Vm
在其内部维持一个可变的借用其中一个领域。因此,Vm
对象将锁定&#34;一旦你打电话给run
,就会自己。这意味着在致电run
后,您无法在Vm
上执行任何其他操作!底线是you can't have a field in a struct that is a reference to a value that is owned by the same struct。