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

Rust生命周期问题:返回含本地闭包引用的futures-signals setter包装结构体报错如何解决

你的思路本身没有问题,报错的核心是你在SetterWrapper中存储了闭包的临时引用,而闭包是wrap_setter函数的局部变量,函数返回后闭包会被销毁,自然会产生悬垂引用错误。

修改方案

第一步:调整SetterWrapper定义

把deser_and_set字段从引用类型改为持有所有权的Box trait对象,绑定和入参Mutable一致的生命周期:

struct SetterWrapper<'a> {
    name: &'static str,
    deser_and_set: Box<dyn Fn(Value) -> Result<(), Error> + 'a>,
    // 其余不相关字段保持不变
}

如果你使用的futures-signals的Mutable是引用计数类型(默认实现就是Arc包装,clone成本极低),也可以选择去掉生命周期约束,后续使用更灵活:

// 无生命周期版本
struct SetterWrapper {
    name: &'static str,
    deser_and_set: Box<dyn Fn(Value) -> Result<(), Error>>,
}

第二步:修改wrap_setter实现

给闭包加上move关键字捕获Mutable的引用/所有权,用Box::new包裹闭包存入包装器:

// 带生命周期版本
fn wrap_setter<'a, T>(name: &'static str, mutable: &'a Mutable<T>) -> SetterWrapper<'a>
    where T: for<'de> Deserialize<'de>
{
    let deser_and_set = move |v: Value| {
        mutable.set(serde_json::from_value::<T>(v)?);
        Ok(())
    };
    SetterWrapper {
        name,
        deser_and_set: Box::new(deser_and_set),
    }
}

如果用无生命周期版本,入参改为直接传Mutable(调用时clone即可):

// 无生命周期版本
fn wrap_setter<T>(name: &'static str, mutable: Mutable<T>) -> SetterWrapper
    where T: for<'de> Deserialize<'de>
{
    let deser_and_set = move |v: Value| {
        mutable.set(serde_json::from_value::<T>(v)?);
        Ok(())
    };
    SetterWrapper {
        name,
        deser_and_set: Box::new(deser_and_set),
    }
}

// 调用示例
let my_int_setter = wrap_setter("my_int", my_int.clone());

修改后原有调用逻辑完全不需要改动,Box<dyn Fn>可以直接像函数引用一样执行。

内容的提问来源于stack exchange,提问作者Felk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:15:01