Можно ли передать функцию 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)()
}

Rust Playground

Компиляция завершается с сообщением об ошибке:

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())),

Другие вопросы по тегам