Rust中Stream存储自引用Future的安全实现疑问
在安全Rust中实现Stream内存储关联生命周期的Future
你的核心问题是:给A加了生命周期'a并让current字段绑定该生命周期后,Stream trait的poll_next方法不允许给自身生命周期'b加'b: 'a约束,导致无法将poll_next中创建的Future存入current——本质是你创建的Future实际绑定的是poll_next调用时的临时生命周期'b,而current要求的是A的生命周期'a,两者无法兼容。
可行的解决思路
1. 去掉A的显式生命周期参数(最直接方案)
如果A里的b是所有权而非引用(如你代码所示),A根本不需要额外的生命周期'a。直接修改定义:
struct A { b: B, current: Option<std::pin::Pin<Box<dyn futures::Future<Output = ()> + '_>>>, }
这里的'_是生命周期省略语法,会自动推导为与A实例绑定的生命周期。在poll_next中,this.b.func()返回的Future绑定的是当前调用的self生命周期'b,完全可以存入current字段。对应的Stream实现也无需额外生命周期参数:
impl futures::Stream for A { type Item = (); fn poll_next( self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> futures::task::Poll<Option<Self::Item>> { let this = self.get_mut(); if let Some(future) = &mut this.current { future.as_mut().poll(cx).map(Some) } else { let future = this.b.func(); this.current = Some(Box::pin(future)); futures::task::Poll::Pending } } }
2. 若A必须保留生命周期'a(如持有其他带生命周期的引用)
如果实际场景中A需要持有'a生命周期的引用(比如另一个Stream),要确保创建的Future绑定'a而非临时的'b:
- 显式让
B::func绑定'a:
此时返回的Future生命周期为impl B { pub async fn func(&'a self) {} }'a,可直接存入current,但这种方式会限制B::func的调用灵活性。 - 使用共享所有权规避引用生命周期限制:
通过use std::sync::Arc; struct B; impl B { pub async fn func(self: Arc<Self>) {} } struct A<'a> { b: Arc<B>, current: Option<std::pin::Pin<Box<dyn futures::Future<Output = ()> + 'a>>>, other_stream: &'a mut dyn futures::Stream<Item = ()>, // 你的其他带生命周期字段 }this.b.clone().func()创建的Future是'static(兼容'a),完全符合current的类型要求。
总结
安全Rust中完全可以实现你的需求,核心是让存储的Future生命周期与A的有效生命周期匹配,避免临时生命周期'b与A的'a冲突。
内容的提问来源于stack exchange,提问作者jk_games
相关产品推荐
相关产品推荐

