0

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)?

HrkBrkkl
  • 613
  • 5
  • 22

1 Answers1

2

you can fix your problem by cloning ptr and moving it into closure like this

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_clone = io.clone();
    let io_closure=Box::new(move |x:isize| io_clone.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]);
}
USA LOVER
  • 145
  • 5