如何在同一数据结构上实现不同复杂顺序的无状态迭代器?
避免内部状态的多顺序迭代器实现方案
不需要给数据结构添加内部状态来切换迭代顺序,推荐以下几种更干净的实现方式:
1. 为每种顺序提供独立的迭代器生成方法
直接给数据结构定义不同的方法,每个方法返回对应顺序的迭代器实例,迭代器自身携带顺序逻辑,完全不影响原数据结构的状态。
示例代码(Rust风格):
// 定义数据结构 struct MyDataStruct { data: Vec<i32>, } // 为简单顺序实现迭代器 struct SimpleIter<'a> { data: &'a Vec<i32>, index: usize, } impl<'a> Iterator for SimpleIter<'a> { type Item = &'a i32; fn next(&mut self) -> Option<Self::Item> { if self.index < self.data.len() { let item = &self.data[self.index]; self.index += 1; Some(item) } else { None } } } // 为复杂顺序1实现迭代器 struct Complex1Iter<'a> { data: &'a Vec<i32>, indices: Vec<usize>, current: usize, } impl<'a> Complex1Iter<'a> { fn new(data: &'a Vec<i32>) -> Self { // 生成复杂顺序的索引序列,比如跳步或特定排序逻辑 let mut indices: Vec<usize> = (0..data.len()).step_by(2).collect(); indices.extend((1..data.len()).step_by(2)); Complex1Iter { data, indices, current: 0 } } } impl<'a> Iterator for Complex1Iter<'a> { type Item = &'a i32; fn next(&mut self) -> Option<Self::Item> { if self.current < self.indices.len() { let idx = self.indices[self.current]; self.current += 1; Some(&self.data[idx]) } else { None } } } // 给数据结构添加方法返回对应迭代器 impl MyDataStruct { fn simple_iter(&self) -> SimpleIter { SimpleIter { data: &self.data, index: 0 } } fn complex1_iter(&self) -> Complex1Iter { Complex1Iter::new(&self.data) } } // 使用方式 fn main() { let ds = MyDataStruct { data: vec![1,2,3,4,5] }; // 简单顺序迭代 println!("Simple order:"); for item in ds.simple_iter() { println!("{}", item); } // 复杂顺序1迭代 println!("Complex1 order:"); for item in ds.complex1_iter() { println!("{}", item); } }
2. 让迭代器生成方法接收顺序参数
如果不想定义太多方法,可以让iter方法接收一个表示顺序的枚举参数,内部根据参数返回对应类型的迭代器。
示例代码:
enum IterOrder { Simple, Complex1, } impl MyDataStruct { fn iter(&self, order: IterOrder) -> Box<dyn Iterator<Item = &i32> + '_> { match order { IterOrder::Simple => Box::new(self.simple_iter()), IterOrder::Complex1 => Box::new(self.complex1_iter()), } } } // 使用方式 fn main() { let ds = MyDataStruct { data: vec![1,2,3,4,5] }; for item in ds.iter(IterOrder::Simple) { println!("{}", item); } for item in ds.iter(IterOrder::Complex1) { println!("{}", item); } }
3. 自定义迭代器适配器
如果基础迭代逻辑可以复用,只需要修改顺序,可以实现一个适配器,接收基础迭代器和顺序逻辑,转换为目标顺序的迭代器。比如预先生成索引序列,再通过索引取元素:
struct OrderedIter<'a, I> where I: Iterator<Item = usize>, { data: &'a Vec<i32>, index_iter: I, } impl<'a, I> Iterator for OrderedIter<'a, I> where I: Iterator<Item = usize>, { type Item = &'a i32; fn next(&mut self) -> Option<Self::Item> { self.index_iter.next().map(|idx| &self.data[idx]) } } impl MyDataStruct { fn ordered_iter<I>(&self, index_iter: I) -> OrderedIter<I> where I: Iterator<Item = usize>, { OrderedIter { data: &self.data, index_iter } } } // 使用方式 fn main() { let ds = MyDataStruct { data: vec![1,2,3,4,5] }; // 简单顺序:直接用0..len的迭代器 let simple_indices = 0..ds.data.len(); for item in ds.ordered_iter(simple_indices) { println!("{}", item); } // 复杂顺序1:自定义索引迭代逻辑 let complex1_indices = (0..ds.data.len()).step_by(2).chain((1..ds.data.len()).step_by(2)); for item in ds.ordered_iter(complex1_indices) { println!("{}", item); } }
以上三种方式都不会给原数据结构引入内部状态,迭代器的顺序逻辑完全由自身或传入的参数控制,同时保证了不同迭代器之间的独立性(可以同时存在多个不同顺序的迭代器实例)。
内容的提问来源于stack exchange,提问作者GumGun
相关产品推荐
相关产品推荐

