如何将 Arc 克隆传递给闭包?

How to pass an Arc clone to a closure?

我正在尝试通过克隆来编写一个使用 Arc 的闭包。理想情况下,我希望将克隆放在闭包内,但我有点被迫通过原始 Arc,这可能是我收到错误的原因:

use std::sync::Arc;
use std::sync::Condvar;
use std::sync::Mutex;
use std::collections::VecDeque;

type Fifo<T> = Arc<(Mutex<VecDeque<T>>, Condvar)>;

fn executor(f: Box<dyn Fn()>) {
    f();
}

fn main() {
    let a = Fifo::<u8>::new(
        (Mutex::new(VecDeque::new()), Condvar::new())
    );
    
    let r = Box::new(||{
        let f = a.clone();
        f.0.lock().unwrap().push_back(0);
    });
    executor(r);
}

错误:

error[E0597]: `a` does not live long enough
  --> src/main.rs:19:17
   |
18 |     let r = Box::new(||{
   |                      -- value captured here
19 |         let f = a.clone();
   |                 ^ borrowed value does not live long enough
...
22 |     executor(r);
   |              - cast requires that `a` is borrowed for `'static`
23 | }
   | - `a` dropped here while still borrowed

error: aborting due to previous error

我想换成

let r = Box::new(||{
    //let f = a.clone();
    a.0.lock().unwrap().push_back(0);
});

会强制闭包决定克隆 a,因此解决了问题,但我得到了同样的错误。

如何将 Arc 传递给闭包?

在闭包外克隆 Arc,然后 move 克隆到闭包中。示例:

use std::collections::VecDeque;
use std::sync::Arc;
use std::sync::Condvar;
use std::sync::Mutex;

type Fifo<T> = Arc<(Mutex<VecDeque<T>>, Condvar)>;

fn executor(f: Box<dyn Fn()>) {
    f();
}

fn main() {
    let a = Fifo::<u8>::new((Mutex::new(VecDeque::new()), Condvar::new()));

    let f = a.clone();
    let r = Box::new(move || {
        f.0.lock().unwrap().push_back(0);
    });

    executor(r);
}

playground