存储来自Fn闭包的返回值



如果&dyn Fn(&mut [u8])更改为&dyn FnOnce(&mut [u8]),则下面的代码有效,因为这样f就可以安全地移动。然而,我真的不能把它变成FnOnce,因为我发现了一些问题。Fn会起作用。

然而,我确实需要捕获结果r,并在consume中返回它,就像下面的一样

use std::sync::Arc;
pub type OnVirtualTunWrite = Arc<dyn Fn(&dyn Fn(&mut [u8]) , usize) -> Result<(), ()> + Send + Sync>;
struct A {
on_virtual_tun_write: OnVirtualTunWrite
}
impl A {
fn consume<R, F>(self, len: usize, f: F) -> Result<R,()>
where
F: FnOnce(&mut [u8]) ->  Result<R,()>,
{
let mut r: Option<Result<R,()>> = None;
let result = (self.on_virtual_tun_write)(&|b: &mut [u8]| {
r = Some(f(b));
}, len);
r.unwrap()
}
}

我知道让它成为Box<dyn FnOnce(&mut [u8])是可行的,但我正在努力避免动态分配。

有没有办法做到这一点?

编译需要两个更改。一种是将consume()函数定义中的F: FnOnce(&mut [u8])...更改为F: Fn(&mut [u8])...FnOn((类型的闭包在调用时会消耗自身,因此只能调用一次。

更改此项将导致另一个错误,r无法在闭包内分配。这是因为r是一个来自闭包外部的捕获变量,Fn((类型将不可变地借用捕获的变量。通过将第二个Fn((更改为FnMut((,r变量将被捕获为可变引用,因此可以从闭包内部分配给:

Arc<dyn Fn(&dyn FnMut(&mut [u8]) , usize) -> Result<(), ()> + Send + Sync>

最新更新