Можно ли передать функцию Arc<RwLock <& Fn () >> в функцию без использования параметра типа?
Я должен пройти Arc<RwLock<&Fn()>>
к функции:
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)()
}
Компиляция завершается с сообщением об ошибке:
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]>>`
Разве это не закрытие Fn
?
Я пытался:
- Замена
Arc<RwLock>
со ссылкой (в результате чего&&Fn()
). Это работает только при удалении одного амперсанда в функции подписиexecute()
, но это не очень помогает мне, потому что по причинам, которые я не хочу здесь объяснять, мне нужны эти обертки. Rust Playground Перемещение
Fn()
вexecute()
подпись функции в предложении where:fn execute(f: Arc<RwLock<&F>>) where F: Fn() { /* ... */ }
Это также работает, но я также не могу использовать предложение where (потому что оно мне понадобится в структуре, но в структурах нет предложений where).
- Объединение двух предыдущих идей: прохождение
Arc<RwLock<&&Fn()>>
и удаление одного амперсанда в функции подписи. Это было бы то, что мне нужно, но это также не удается. - Кастинг
wrapped_closure
вArc<RwLock<&Fn()>>
(это было решением подобной проблемы здесь). Это терпит неудачу, поскольку это "не примитивный актерский состав"
Можно ли пройти Arc<RwLock<&Fn()>>
в Rust без добавления параметра типа и предложения where? Если да, то как?
1 ответ
Решение
Решение от Shepmaster и взято из комментариев.
Хитрость заключается в том, чтобы создать ссылку на закрытие &Fn
, заменяя Arc::new(RwLock::new(&closure))
с Arc::new(RwLock::new(
&closure as &Fn()
))
,