如何声明存储带Clone trait的闭包的Vec类型?
存储可克隆闭包的结构体正确声明方式
方案一:泛型结构体(存同类型闭包)
如果你的所有闭包都是同一种类型(比如都不捕获环境,或者捕获的环境完全一致),用泛型约束是最简单高效的方式:
pub struct Equations<F> where F: Fn(f32) -> f32 + Clone, { eqns: Vec<F>, }
这种方式是静态分发,没有运行时开销,但同一个Equations实例里只能装同一种闭包。
方案二:动态分发(存不同类型闭包)
如果需要混合存储不同类型的闭包,就得用动态分发。但Clone trait本身不支持动态对象(因为它的clone方法返回Self,动态分发时无法确定Self的大小),所以得自定义一个兼容的trait:
// 自定义对象安全的trait,整合函数调用和克隆能力 trait CloneFn: Fn(f32) -> f32 { fn clone_box(&self) -> Box<dyn CloneFn>; } // 为所有符合条件的闭包自动实现这个trait impl<F> CloneFn for F where F: Fn(f32) -> f32 + Clone + 'static, { fn clone_box(&self) -> Box<dyn CloneFn> { Box::new(self.clone()) } } // 给Box<dyn CloneFn>手动实现Clone,调用内部的clone_box方法 impl Clone for Box<dyn CloneFn> { fn clone(&self) -> Self { (**self).clone_box() } } // 最终的结构体定义 pub struct Equations { eqns: Vec<Box<dyn CloneFn>>, }
这样就能在Equations里存各种不同类型、但都能克隆的闭包了。
你的尝试为什么失败?
- 第一次用
impl Fn(f32)->f32 + Clone当字段类型:impl Trait只能用在函数的参数或返回值里,不能直接作为结构体字段的类型。 - 第二次自定义
trait AnonFunction:你没给闭包类型实现这个trait,而且没解决Clone的对象安全问题,所以没法直接用dyn AnonFunction。
内容的提问来源于stack exchange,提问作者dim_voly
相关产品推荐
相关产品推荐

