如何在Rust中免样板代码组合迭代器适配器?支持genawaiter
实现 Iterator.compose 方法以组合 genawaiter 迭代器
要实现类似 iterator.compose(fn) 的用法,你可以通过扩展 Rust 的 Iterator trait来添加自定义的 compose 方法,直接在任意迭代器上调用该方法,避免重复编写样板代码。
步骤1:定义扩展 trait
创建一个自定义 trait,为所有迭代器提供 compose 方法:
use std::iter::Iterator; // 定义扩展 trait,添加 compose 方法 trait IteratorCompose: Iterator { /// 将当前迭代器传入指定函数,返回新的迭代器 fn compose<F, O>(self, f: F) -> O where F: FnOnce(Self) -> O, O: Iterator, { f(self) } } // 为所有实现了 Iterator 的类型自动实现这个扩展 trait impl<I: Iterator> IteratorCompose for I {}
步骤2:结合 genawaiter 使用
现在可以直接在迭代器上调用 compose 方法,传入你的适配器函数:
use genawaiter::{rc::gen, yield_}; fn wrap_with_option<Input, I: Iterator<Item = Input>>(iter: I) -> impl Iterator<Item = Option<Input>> { gen!({ for item in iter { yield_!(Some(item)); } }).into_iter() } fn run() { let input: Vec<i32> = vec![1, 2, 3, 4, 5]; let output: Vec<Option<&i32>> = input .iter() .compose(wrap_with_option) .collect(); let expected = vec![Some(&1), Some(&2), Some(&3), Some(&4), Some(&5)]; assert_eq!(output, expected); }
说明
compose方法的核心逻辑是将当前迭代器自身作为参数传给传入的函数,并直接返回函数的结果,完全适配需要维护状态的迭代器场景(比如 genawaiter 生成的带状态迭代器)。- 由于为所有
Iterator实现了IteratorComposetrait,任何迭代器都能直接调用compose,无需为每个适配器单独编写适配代码。
内容的提问来源于stack exchange,提问作者Raz Luvaton
相关产品推荐
相关产品推荐

