简体   繁体   English

与/不了解Rust借阅检查器打架

[英]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))
                },

                _ => ()
            };
        };
    }
}

full code here 完整的代码在这里

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 . 因此,一旦调用runVm对象将“锁定”自身。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM