struct MyData {
data: Vec<Vec<i32>>,
}
struct MyIterator<'a> {
data: &'a [Vec<i32>],
row_index: usize,
col_index: usize,
}
impl MyData {
fn new(data: Vec<Vec<i32>>) -> Self {
MyData { data }
}
fn iter(&self) -> MyIterator {
MyIterator {
data: &self.data,
row_index: 0,
col_index: 0,
}
}
}
impl<'a> Iterator for MyIterator<'a> {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
while self.row_index < self.data.len() {
if self.col_index < self.data[self.row_index].len() {
let value = self.data[self.row_index][self.col_index];
self.col_index += 1;
if value >= 0 {
return Some(value);
}
} else {
self.row_index += 1;
self.col_index = 0;
}
}
None
}
}
处理 Iterator
trait 中的方法
type Item
: 定义迭代器返回的元素类型,这里是 i32
。
next
: 每次调用 next
方法,尝试返回下一个非负数。首先检查当前行是否遍历完,如果没有,获取当前元素并检查是否为非负数,如果是则返回;如果当前行遍历完,移动到下一行并重置列索引。如果所有行都遍历完,返回 None
。
自定义迭代器相较于标准迭代器的优势和劣势
- 优势:
- 定制化:可以根据特定需求定制遍历逻辑,如这里按行优先且跳过负数,标准迭代器通常没有这么灵活的控制。
- 减少内存开销:在一些特定场景下,自定义迭代器可以避免标准迭代器在通用功能实现中产生的额外开销。
- 劣势:
- 复杂性:实现自定义迭代器需要更多的代码和对 Rust 迭代器机制的深入理解,相比使用标准迭代器更易出错。
- 通用性差:标准迭代器适用于各种标准集合类型,自定义迭代器通常仅适用于特定数据结构,复用性低。