You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:15:39