繁体   English   中英

如何使用对结构外部的可变引用将闭包保存在结构中?

[英]How to save a closure in a Struct with a mutable reference to outside the struct?

我正在尝试制作一台可以像这样关闭 output 的堆栈机器:

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 }
}

通常我希望它只打印这样的结果|x:isize|println,("{}",x) 但是为了测试我想在一个变量中捕获 output:

#[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]);
}

但我遇到了一些困难。 告诉我必须将 io 数组放入 Arc<Mutex<>>。 让我产生了将 Closure 放入 Box 的想法。 但我不知道如何让它一起工作以及为什么我得到错误。 错误信息:

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

为什么 io 的寿命不够长? io 不是一直活到测试结束并且和我的闭包有相同的寿命吗? 有没有更好的方法来做我想做的事情(将闭包传递给可以改变结构外部变量的结构)?

您可以通过克隆 ptr 并将其移至关闭状态来解决您的问题

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]);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM