I'm trying to write a closure that uses an Arc by cloning it. Ideally I'd like to have the clone inside the closure, but I'm kinda forced to pass the original Arc, which might be the reason I'm getting the error:
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:
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
I thought changing to
let r = Box::new(||{
//let f = a.clone();
a.0.lock().unwrap().push_back(0);
});
would force the closure to decide to clone a, therefore fixing the problem, but I get the same error.
How can I pass an Arc to a closure?
Clone the Arc outside the closure and then move the clone into the closure. Example:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With