Rust中如何在不装箱(boxing)的情况下存储Future?
问题分析
你的代码报错核心原因是:Stored的泛型参数F由调用store时传入的参数类型决定,但你在方法内部直接赋值了async {}生成的匿名Future——这个匿名Future的类型和泛型参数F完全不匹配,编译器无法将两者关联,因此抛出类型不匹配错误。
解决方案(无需装箱)
既然所有存储的Future类型完全一致,我们可以通过以下两种方式实现类型匹配:
方案一:绑定固定匿名Future类型
通过构造函数让Stored的泛型参数固定为目标匿名Future的类型,确保store方法存入的Future类型与结构体泛型一致:
use futures::Future; struct Stored<F: Future<Output = ()>> { f: Option<F>, } // 生成固定类型的匿名Future fn create_future() -> impl Future<Output = ()> { async {} } impl<F: Future<Output = ()>> Stored<F> { // 构造空实例,要求F支持默认初始化 fn new() -> Self where F: Default { Stored { f: None } } // 直接存入固定类型的Future fn store(&mut self) { self.f = Some(create_future()); } } // 使用示例 fn main() { let mut stored: Stored<_> = Stored::new(); stored.store(); }
方案二:私有模块隐藏类型细节
如果希望对外暴露更简洁的接口,可以用私有模块封装内部泛型逻辑,对外只提供固定类型的Stored实例:
use futures::Future; mod private { use super::*; pub struct Stored<F: Future<Output = ()>> { pub f: Option<F>, } // 返回绑定了固定匿名Future类型的Stored实例 pub fn create_stored() -> Stored<impl Future<Output = ()>> { Stored { f: None } } // 仅允许存入匹配类型的Future pub fn store_future(stored: &mut Stored<impl Future<Output = ()>>) { stored.f = Some(async {}); } } // 对外导出必要接口 pub use private::{Stored, create_stored, store_future}; // 使用示例 fn main() { let mut stored = create_stored(); store_future(&mut stored); }
补充:若实际需求是存储传入的Future
如果是代码笔误,你原本想存储store方法传入的F类型Future,只需移除内部覆盖的let f = async {};即可:
use futures::Future; struct Stored<F: Future<Output = ()>> { f: Option<F>, } impl<F: Future<Output = ()>> Stored<F> { fn store(&mut self, f: F) { self.f = Some(f); } }
内容的提问来源于stack exchange,提问作者Gabriel Machado
相关产品推荐
相关产品推荐

