如何在Rust结构体中存储返回闭包的闭包?
在Rust结构体中存储返回回调的函数
要在Rust结构体中存储一个返回另一个回调的函数,核心要解决闭包的类型定义问题——Rust闭包是匿名类型,结构体字段需要明确的类型声明,这里提供两种实用实现方式:
方式一:使用 trait 对象(灵活通用)
通过Box<dyn Fn(...) -> ...>擦除闭包的具体类型,适合需要统一结构体类型、支持不同闭包实例的场景:
struct Strategy { // 外层函数:无参数,返回一个无参数无返回值的闭包(trait 对象) callback: Box<dyn Fn() -> Box<dyn Fn()>>, } fn main() { let strategy = Strategy { callback: Box::new(|| { println!("strategy_init"); // 内层闭包同样包装为 trait 对象返回 Box::new(|| println!("strategy_update")) }), }; // 调用流程:先执行外层回调拿到内层函数,再执行内层函数 let update_fn = (strategy.callback)(); update_fn(); }
补充说明
- 外层闭包通过
Box::new实现Fn() -> Box<dyn Fn()>trait,适配结构体字段的 trait 对象类型 - 内层闭包也需要用
Box::new包裹,转为dyn Fn()trait 对象返回 - 如果闭包需要可变捕获环境,可以把
Fn替换为FnMut,比如Box<dyn FnMut() -> Box<dyn FnMut()>>
方式二:使用泛型结构体(零堆分配)
如果不需要统一结构体类型,且闭包的具体类型固定,可以用泛型避免堆分配,性能更优:
// 泛型参数F表示外层函数类型,G表示返回的内层函数类型 struct Strategy<F, G> where F: Fn() -> G, G: Fn(), { callback: F, } fn main() { let strategy = Strategy { callback: || { println!("strategy_init"); || println!("strategy_update") }, }; let update_fn = (strategy.callback)(); update_fn(); }
补充说明
- 泛型会自动推导闭包的匿名类型,不需要额外包装
- 缺点是不同闭包实例对应的
Strategy类型不同,无法放在同一集合(比如Vec<Strategy>)中,灵活性不如 trait 对象方式
内容的提问来源于stack exchange,提问作者user11420374
相关产品推荐
相关产品推荐

