自定义类型未实现futures::Stream trait的异步更新系统问题
问题分析
你遇到的编译错误核心原因是嵌套Future导致的类型不匹配:
- 用
future::lazy包裹返回async块的闭包后,最终得到的是嵌套Future:Future<Output=Future<Output=Either<Stream, Stream>>>。 flatten_stream方法要求调用它的Future的输出必须是直接的Stream(即Future<Output=Stream>),但你的场景中输出是另一个Future,因此不满足 trait 约束要求。
修复方案
用futures::stream::once替代future::lazy,再通过flatten()将"产生Stream的Stream"扁平化,即可得到目标类型的Stream:
use futures::stream::{self, StreamExt}; // ... let repair_stream = stream::once(async move { let mut failures = { let state = &mut *shared_state_r.borrow_mut(); state.previous_failures = mem::take(&mut state.failures); state.previous_failures.clone() }; if !failures.is_empty() { failures.sort(); global_progression_r.lock().await.stage = UpdateStage::FindingRepairPath; Either::Left( update_internal( update_options_r, file_manager_r, global_progression_r, State::New, // 强制从无起始版本开始修复 shared_state_r, repository, goal_version_r, UpdateFilter { failures }, UpdateStage::Repairing, ) .try_flatten_stream(), ) } else { // 无需要修复的内容,返回空流 Either::Right(stream::empty()) } }) .flatten();
关键说明
stream::once的作用:将异步逻辑(async块)包装成仅产生单个元素的Stream,这个元素就是你要返回的Either<Stream, Stream>。flatten()的作用:将"包含Stream的Stream"扁平化,直接输出内部Stream的所有元素,匹配你需要的repair_stream类型。- 类型统一(可选):如果
update_internal返回的Stream和stream::empty()的具体类型不一致,可使用Box::pin将它们转换成BoxStream<'_, Result<SharedUpdateProgress, UpdateError>>,确保Either两个分支类型匹配,示例:use futures::stream::BoxStream; // Left分支 Either::Left(Box::pin(update_internal(...).try_flatten_stream()) as BoxStream<_>) // Right分支 Either::Right(Box::pin(stream::empty()) as BoxStream<_>)
内容的提问来源于stack exchange,提问作者Vana
相关产品推荐
相关产品推荐

