[英]Fighting with / not understanding Rust borrow checker
I started writing Rust code a few days ago, and just now had my first encounter with the borrow checker. 几天前,我开始编写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 gives me the following errors: 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
I don't understand why it's getting borrowed twice. 我不明白为什么要借两次。 What's going on? 这是怎么回事?
The value you push on the stack keeps a mutable borrow on self.frames
active. 您压入堆栈的值使self.frames
上的可变借位self.frames
活动状态。 On the second loop iteration, that borrow is still active, so you can't take a second borrow on self.frames
. 在第二个循环迭代中,该借用仍然处于活动状态,因此您不能对self.frames
进行第二次借用。
Vm::literal_to_value
doesn't need a mutable reference to the activation object, so you can change your code to take an immutable reference instead: 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))
},
_ => ()
};
That makes run
compile, but then your tests fail to compile. 这样可以run
编译,但随后测试将无法编译。 That's because with this signature: 那是因为有了这个签名:
pub fn run(&'a mut self)
you're linking the lifetime of self
with the lifetime parameter on Vm
. 您正在将self
的生存期与Vm
上的lifetime参数链接起来。 Essentially, the type of self
here is &'a mut Vm<'a>
; 本质上,这里的self
类型是&'a mut Vm<'a>
; the fact that 'a
occurs twice here, combined with the fact that it's a mutable borrow (rather than an immutable borrow) tells Rust that the Vm
maintains a mutable borrow on itself within one of its fields . 'a
在这里发生两次的事实,加上它是可变借贷(而不是不可变借贷)这一事实告诉Rust, Vm
在其一个字段中对自己保持可变借借 。 Therefore, the Vm
object will "lock" itself once you call run
. 因此,一旦调用run
, Vm
对象将“锁定”自身。 That means that after calling run
, you can't do anything else on the Vm
! 这意味着在调用run
,您将无法在Vm
上执行任何其他操作! The bottom line is that you can't have a field in a struct that is a reference to a value that is owned by the same struct . 最重要的是, 您不能在结构中有一个字段引用相同结构所拥有的值 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.