我试图建立一个语言解释器。有一个要求,以维护一个符号表的命令,作为机器状态的一部分。命令本身需要能够添加新的命令到符号表。
我目前所掌握的情况如下:
struct Machine<'a> {
dict: HashMap<&'a str, Box<dyn Fn(&mut Machine) -> ()>>,
}
对于执行符号表中命令的解释器函数,我有(简化):
fn exec(m: &mut Machine, instr: &str) {
let f = m.dict.get(instr).unwrap();
f(m);
}
这给了我一个编译器错误:
error[E0502]: cannot borrow `*m` as mutable because it is also borrowed as immutable
--> src/mre.rs:9:5
|
8 | let f = m.dict.get(instr).unwrap();
| ----------------- immutable borrow occurs here
9 | f(m);
| -^^^
| |
| mutable borrow occurs here
| immutable borrow later used by call
我知道为什么这样做不安全毕竟命令被允许从符号表中删除它自己的条目,我认为正确的方法是在使用f
之前克隆它,这样m.dict
的借用可以在调用f
之前结束。
天真的尝试给了我:
一个三个三个一个Box<T>
实现了Clone
,当满足某些条件时,闭包是Clone
,所以这看起来像是一种进步,但我不确定具体如何实现。
正确的做法是什么?
1条答案
按热度按时间blmhpbnm1#
您可以:
Arc<dyn Fn(&mut Machine)>
(或Rc
),它始终是可克隆的。remove()
返回一个拥有值,这样您就可以调用函数并将其插回。You can also clone a trait object, but this is complicated .