I have to pass a Arc<RwLock<&Fn()>>
to a function:
use std::sync::{Arc, RwLock};
fn main() {
let closure = || println!("Hello World");
let wrapped_closure = Arc::new(RwLock::new(&closure));
execute(wrapped_closure);
}
fn execute(f: Arc<RwLock<&Fn()>>) {
let rw_lock_read_guard = f.read().unwrap();
(rw_lock_read_guard)()
}
Compilation fails with the error message:
error[E0308]: mismatched types
--> src/main.rs:6:13
|
6 | execute(wrapped_closure);
| ^^^^^^^^^^^^^^^ expected trait std::ops::Fn, found closure
|
= note: expected type `std::sync::Arc<std::sync::RwLock<&std::ops::Fn()>>`
found type `std::sync::Arc<std::sync::RwLock<&[closure@src/main.rs:4:19: 4:45]>>`
Isn't the closure an Fn
?
I have tried:
- Replacing the
Arc<RwLock>
with a reference (resulting in&&Fn()
). This only works when you remove one ampersand in the function signature ofexecute()
, but that doesn't really help me, because for reasons I don't want to explain here, I need those wrappers. Rust Playground Moving the
Fn()
in theexecute()
function signature into a where clause:fn execute(f: Arc<RwLock<&F>>) where F: Fn() { /* ... */ }
That also works, but I cannot use a where clause either (because I would need it in a struct, but in structs there are no where clauses).
- Combining the two previous ideas: Passing a
Arc<RwLock<&&Fn()>>
and removing one ampersand in the function signature. That would be what I need, but it also fails. - Casting
wrapped_closure
into anArc<RwLock<&Fn()>>
(this was the solution to a similar problem here). This fails as it's a "non-primitive cast"
Is it possible to pass an Arc<RwLock<&Fn()>>
in Rust without adding a type parameter and a where clause? If yes, how?