I am trying to make an stack machine where that can take a closure for the output like this:
pub struct VirtualMachine {
stack: Vec<isize>,
code: Vec<Op>,
code_pointer: usize,
io_dest: Box<dyn Fn(isize)>,
}
impl VirtualMachine {
pub fn new(io_dest: Box<dyn Fn(isize)>) -> VirtualMachine {
VirtualMachine { stack: vec![], code: vec![], code_pointer: 0, io_dest }
}
Normaly i want it to just print the results like this |x:isize|println!("{}",x)
. But for testing i want to catch the output in a variablle:
#[test]
fn test_simple_add() {
let code = vec![Op::Push(1),Op::Push(2),Op::Add];
let mut io= Arc::new(Mutex::new(vec![]));
let io_closure=Box::new(|x:isize|io.lock().unwrap().push(x)); //<-- error borrowed value does not live long enough
let mut virtual_machine = VirtualMachine::new(io_closure);
virtual_machine.run();
assert_eq!(3, io.lock().unwrap()[0]);
}
But i am running in some difficulties. This tells me i have to put my io array in Arc<Mutex<>>. This gave me the idea to put the Closure in a Box. But i have no idea how to make it work together and why i get the error. Error message:
--> src\virtual_machine.rs:98:45
|
98 | let io_closure=Box::new(|x:isize| { io.lock().unwrap().push(x); });
| --------- ^^ borrowed value does not live long enough
| |
| value captured here
99 | let mut virtual_machine = VirtualMachine::new(io_closure);
| ---------- cast requires that `io` is borrowed for `'static`
...
102 | }
| - `io` dropped here while still borrowed
Why is io not living long enough? Isn't io alive until the end of the test and has the same lifetime as my closure? Is there a better way to do what i am trying to do (Passing a closure to a struct which can mutate a varibale outside the struct)?