Rust 无法为<;移动dyn类型的值';r>;FnOnce(&;x27;r mut[u8]):用于<';r>;FnOnce(&;x27;r mut[u8])无法静态确定

Rust 无法为<;移动dyn类型的值';r>;FnOnce(&;x27;r mut[u8]):用于<';r>;FnOnce(&;x27;r mut[u8])无法静态确定,rust,Rust,我试图在线程之间共享一个函数,该函数可以通过另一个函数调用: fn main() { let on_virtual_tun_write = std::sync::Arc::new(|f: &dyn FnOnce(&mut [u8]), size: usize|-> std::result::Result<(),()>{ let mut buffer = vec![0; size]; f(buffer.as_mut_slic

我试图在线程之间共享一个函数,该函数可以通过另一个函数调用:

fn main() {
    let on_virtual_tun_write = std::sync::Arc::new(|f: &dyn FnOnce(&mut [u8]), size: usize|-> std::result::Result<(),()>{
        let mut buffer = vec![0; size];
        f(buffer.as_mut_slice());
        Ok(())
    });
}

所以我认为有几个问题共同导致了这个问题

我将使用一个简化的示例,它生成基本相同的错误消息

fn main() { 
  let ff = |f: &dyn FnOnce()| { f(); };
}
问题的核心是,生锈是阻止坏代码,因为
FnOnce
被多次使用。像这样(不编译):

首先,
FnOnce()
当被调用时,它会消耗自身——这就是它如何确保它只能被调用一次。这意味着您需要传递的是对象,而不是对它的引用,否则调用方仍然可以持有引用。对于
Fn()
FnMut()
,情况并非如此。第一个只使用对self的引用,第二个是对self的可变引用。这意味着以下编译正常:

fn main() { 
    let ff = |f: &dyn Fn()| { f(); };
    let f = || {};
    ff(f); // First call is OK
    f(); // Second usage is OK - it's a pure function

    let ff = |f: &mut dyn FnMut()| { f(); };
    let mut i = 0;
    let mut f = || { i += 1 };
    ff(&mut f); // OK i=1
    f(); // OK i=2
    println!("i={}", i); // prints 2

}
因此,如果您可以减少对函数类型的限制,使其成为
Fn
FnMut
,那么应该可以为您解决这个问题,如果不是的话。。。继续读下去

您可以将
FnOnce
的实例(而不是引用)传递给使用
impl
的通用函数。e、 g

fn ff(f: impl FnOnce()) {
  f()
}

fn main() {
   // Creating a closure that moves q into it ensures we get a FnOnce
   let q=vec![1,2,3];
   let f = move || {println!("{}", q.len())};

   ff(f); // OK.
   // f(); // Compile error with "use of moved value: `f`"
}
这相当于

fn<F> ff(f: F)
    where F: FnOnce()
{
  f()
}

Yuu可以将这个示例简化为
fn main(){let ff=|f:&dyn FnOnce()|{f();};}
,并且仍然得到基本相同的错误消息。
fn ff(f: impl FnOnce()) {
  f()
}

fn main() {
   // Creating a closure that moves q into it ensures we get a FnOnce
   let q=vec![1,2,3];
   let f = move || {println!("{}", q.len())};

   ff(f); // OK.
   // f(); // Compile error with "use of moved value: `f`"
}
fn<F> ff(f: F)
    where F: FnOnce()
{
  f()
}
fn main() {
   let ff = |f: Box<dyn FnOnce()>| { f() };
   let q=vec![1,2,3];
   let f = Box::new(move || {println!("{}", q.len())});
   ff(f); // OK
   // f(); // Errors with "use of moved value: `f`"
}