0

我必须将 a 传递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(),但这并没有真正帮助我,因为出于我不想在这里解释的原因,我需要那些包装器。锈游乐场
  • 将函数签名中的Fn()in移动execute()到 where 子句中:

    fn execute(f: Arc<RwLock<&F>>) where F: Fn() { /* ... */ }
    

    这也有效,我也不能使用 where 子句(因为我需要在结构中使用它,但在结构中没有 where 子句)。

  • 结合前面的两个想法:Arc<RwLock<&&Fn()>>在函数签名中传递 a 并删除一个 & 符号。那将是我所需要的,但它也失败了。
  • 铸造wrapped_closure成(这是这里Arc<RwLock<&Fn()>>类似问题的解决方案)。这失败了,因为它是“非原始演员表”

是否可以在不添加类型参数和 where 子句的情况下传递Arc<RwLock<&Fn()>>in Rust?如果是,如何?

4

1 回答 1

3

解决方案由 Shepmaster 提供,取自评论。

诀窍是将闭包引用转换为 a &Fn,替换Arc::new(RwLock::new(&closure))为。Arc::new(RwLock::new(&closure as &Fn()))

于 2018-06-19T19:40:54.647 回答