如何存储使用封闭状态的 Rust 闭包
How to store Rust closures that use enclosing state
我找到了两种方法 return 从使用封闭状态的函数中闭包:
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;
}
现在,我需要将输出对象存储到一个结构中,并且还能够克隆它。
不幸的是,在第二种情况下,特征 impl
对象不能位于结构位置。
struct A {
b: impl Fn(u64) -> u64
}
这失败了:impl Trait
不允许超出函数和方法 return 类型。
在第一个示例中,无法复制或克隆装箱的动态特征对象。
fn duplicate(f: Box<dyn Fn(u64) -> u64>) -> Box<dyn Fn(u64) -> u64> {
f.clone()
}
这失败并出现错误“不满足 dyn Fn(u64) -> u64: Clone
”
创建闭包存储的惯用方法是什么:
- 闭包可以重复
- 每个闭包都可以捕获一些封闭状态
我正在考虑的一个选择是让这些函数 return 一个闭包 return 闭包,但这似乎有问题。
您可以使用自定义方法来克隆 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
来命名第二种方法的return类型:
#![feature(type_alias_impl_trait)]
type ClosureType = impl Fn(u64) -> u64 + Clone;
fn closure_try(t: u64) -> ClosureType {
move |x: u64| x + t
}
后一种方法性能更高,但 nightly-only 截至今天。
我找到了两种方法 return 从使用封闭状态的函数中闭包:
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;
}
现在,我需要将输出对象存储到一个结构中,并且还能够克隆它。
不幸的是,在第二种情况下,特征 impl
对象不能位于结构位置。
struct A {
b: impl Fn(u64) -> u64
}
这失败了:impl Trait
不允许超出函数和方法 return 类型。
在第一个示例中,无法复制或克隆装箱的动态特征对象。
fn duplicate(f: Box<dyn Fn(u64) -> u64>) -> Box<dyn Fn(u64) -> u64> {
f.clone()
}
这失败并出现错误“不满足 dyn Fn(u64) -> u64: Clone
”
创建闭包存储的惯用方法是什么:
- 闭包可以重复
- 每个闭包都可以捕获一些封闭状态
我正在考虑的一个选择是让这些函数 return 一个闭包 return 闭包,但这似乎有问题。
您可以使用自定义方法来克隆 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
来命名第二种方法的return类型:
#![feature(type_alias_impl_trait)]
type ClosureType = impl Fn(u64) -> u64 + Clone;
fn closure_try(t: u64) -> ClosureType {
move |x: u64| x + t
}
后一种方法性能更高,但 nightly-only 截至今天。