我想在拥有这些功能的结构上应用某些功能。

第一次尝试:

struct VM {
    buffer: Vec<fn(&mut VM)>,
    stack: Vec<isize>,
}

impl VM {
    fn new() -> VM {
        VM {
            buffer: vec![VM::op_zero, VM::op_drop],
            stack: vec![],
        }
    }
    fn op_zero(&mut self) { self.stack.push(0); }
    fn op_drop(&mut self) {
        match self.stack.pop() {
            Some(i) => println!("drop {}", i),
            None => println!("stack underflow!")
        }
    }
    fn evaluate(&mut self) {
        for op in self.buffer {
            op(self);
        }
    }
}

fn main() {
    let mut vm = VM::new();
    vm.evaluate();
}

由于移出借用的内容,因此无法正常工作。我在&之前添加了self.buffer,但是它仍然不起作用,因为self.buffer也被借为不可变的。
fn evaluate(&mut self) {
    for op in &self.buffer {
        op(self);
    }
}

第三次尝试有效,但具有在数组索引上运行时范围检查的开销:
fn evaluate(&mut self) {
    let len = self.buffer.len();
    for i in 0..len {
        let op = self.buffer[i];
        op(self);
    }
}

有更好的方法来解决借阅检查器吗?

最佳答案

您实际上不应该尝试“解决借阅检查器”。它阻止了您执行此操作,因为无法保证您调用的op不会与您要迭代的缓冲区混在一起。实际上,您的最终代码也存在相同的问题:op可能会截断缓冲区,从而导致您尝试越过向量末尾时出现 panic 。

一种安全的方法是在评估时换出buffer。假设您不打算对同一指令序列进行多次评估:

fn evaluate(&mut self) {
    use std::mem;
    for op in mem::replace(&mut self.buffer, vec![]) {
        op(self);
    }
}

在这种情况下,可以通过调用的op修改新缓冲区,而不会干扰evaluate

关于iterator - 在拥有这些功能的结构上应用一些功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34564944/

10-11 18:34