gpt4 book ai didi

iterator - 在拥有这些函数的结构上应用一些函数

转载 作者:行者123 更新时间:2023-11-29 08:05:24 25 4
gpt4 key购买 nike

我想在拥有这些函数的结构上应用一些函数。

第一次尝试:

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也是借来的immutable。

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com