我发现了两种从使用封闭状态的函数返回闭包的方法:
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
}
游乐场
后一种方法更具表演性,但仅限于今天的夜间。