如何存储使用封闭状态的Rust闭包



我发现了两种从使用封闭状态的函数返回闭包的方法:

fn closure_try(t: u64) -> Box<dyn Fn(u64) -> u64> {
let f = |x: u64| x + t;
return Box::new(f);
}
fn closure_try2(t: u64) -> impl Fn(u64) -> u64 {
let f = move |x: u64| x + t.clone();
return f;
}

现在,我需要将输出对象存储到一个结构中,并能够克隆它

不幸的是,在第二个实例中,traitimpl对象不能位于结构位置。

struct A {
b: impl Fn(u64) -> u64
}

失败的原因是:函数和方法返回类型之外不允许使用impl Trait

在第一个示例中,不能复制或克隆装箱的动态特征对象。

fn duplicate(f: Box<dyn Fn(u64) -> u64>) -> Box<dyn Fn(u64) -> u64> {
f.clone()
}

这失败了,错误为"0";不满足CCD_ 3";

创建闭包存储的惯用方法是什么?其中:

  • 闭包可以重复
  • 每个闭包都可以捕获一些封闭状态

我正在考虑的一个选项是让这些函数返回一个返回闭包的闭包,但这似乎有问题。

您可以使用自定义方法克隆Box<dyn Trait>,请参阅如何克隆存储装箱特征对象的结构?:

trait ClonableFn: Fn(u64) -> u64 {
fn clone_box(&self) -> Box<dyn ClonableFn>;
}
impl Clone for Box<dyn ClonableFn> {
fn clone(&self) -> Self {
<dyn ClonableFn>::clone_box(&**self)
}
}
impl<T> ClonableFn for T
where
T: 'static + Fn(u64) -> u64 + Clone,
{
fn clone_box(&self) -> Box<dyn ClonableFn> {
Box::new(T::clone(self))
}
}
fn closure_try(t: u64) -> Box<dyn ClonableFn> {
let f = move |x: u64| x + t;
Box::new(f)
}

游乐场。

或者,您可以使用不稳定的特性type_alias_impl_trait来命名第二种方法的返回类型:

#![feature(type_alias_impl_trait)]
type ClosureType = impl Fn(u64) -> u64 + Clone;
fn closure_try(t: u64) -> ClosureType {
move |x: u64| x + t
}

游乐场

后一种方法更具表演性,但仅限于今天的夜间。

最新更新