我正在尝试编写一个chip8模拟器,借用检查器让我很难过。
想法是通过查找HashMap
内的方法指针然后执行此方法指针来解码操作码,但我无法使可变方法指针正常工作:
struct Chip8 {
opcode: u16,
//... other fields
jump_table: HashMap<u16, Box<fn(&mut Chip8)>>,
}
使用指针的功能:
fn execute_decoded(&mut self, key: u16) {
let func = self.jump_table.get(&key);
match func {
Some(func) => func(self),
None => {
println!("invalid op: {}", self.opcode);
sleep(Duration::from_millis(10000));
return;
}
}();
self.program_counter = self.program_counter + 2;
}
检查员抱怨:
cannot borrow `*self` as mutable because `self.jump_table` is also borrowed as immutable
--> main.rs:168:36
|
165 | let func = self.jump_table.get(&key);
| --------------- immutable borrow occurs here
...
168 | Some(func) => func(self),
| ^^^^ mutable borrow occurs here
...
178 | }
| - immutable borrow ends here
我不明白为什么会发生这种错误。
为什么self.jump_table.get(&key)
会借用?基于execute_decoded
的签名,我假设它适用于self
的可变借用版本,并且不需要额外的借用。
答案 0 :(得分:4)
没有理由Box
HashMap
中的HashMap
函数指针,只引入不需要的间接。
与already been mentioned一样,你正在借用函数指针。问题是,没有理由。您只需复制函数指针即可将其与use std::collections::HashMap;
struct Chip8 {
jump_table: HashMap<u16, fn(&mut Chip8)>,
}
impl Chip8 {
fn execute_decoded(&mut self, key: u16) {
let func = self.jump_table.get(&key).map(|x| *x);
match func {
Some(func) => func(self),
None => {
println!("invalid op");
}
};
}
}
fn main() {}
:
private void videoSource_New( object sender, ref Bitmap image )
答案 1 :(得分:2)
Rust中的HashMap
拥有其中的所有内容。为了得到你的函数指针,你要用let func = self.jump_table.get(&key);
借用它。现在,func
无法借用 self.jump_table
(self
的元素)。
问题是您正试图将self
全部传递到func
。如果您以不可变的方式传递self
,这样会很好,因为您可以根据需要多次借用self
。但是,由于您尝试可变地借用self
,编译器将不允许您这样做,因为您只是不可避免地借用了self
的部分(具体为self.jump_table
})。
解决此问题的一种方法是将Chip8
结构体拆分为较小的结构体,这样您就可以将所有必要的信息传递到func
,而无需传入jump_table
。< / p>