MST

星途 面试题库

面试题:自定义Rust迭代器在复杂集合操作中的应用

假设你有一个自定义结构体`MyData`,它包含一个`Vec<Vec<i32>>`,表示一个二维数组。现在需要实现一个自定义迭代器,能够按行优先的顺序遍历这个二维数组中的所有元素,同时支持在遍历过程中跳过所有负数。请编写代码实现这个自定义迭代器,并说明在实现过程中如何正确处理`Iterator` trait中的各种方法,以及在复杂集合操作场景下自定义迭代器相较于标准迭代器的优势和劣势。
35.1万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
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 中的方法

  1. type Item: 定义迭代器返回的元素类型,这里是 i32
  2. next: 每次调用 next 方法,尝试返回下一个非负数。首先检查当前行是否遍历完,如果没有,获取当前元素并检查是否为非负数,如果是则返回;如果当前行遍历完,移动到下一行并重置列索引。如果所有行都遍历完,返回 None

自定义迭代器相较于标准迭代器的优势和劣势

  • 优势
    • 定制化:可以根据特定需求定制遍历逻辑,如这里按行优先且跳过负数,标准迭代器通常没有这么灵活的控制。
    • 减少内存开销:在一些特定场景下,自定义迭代器可以避免标准迭代器在通用功能实现中产生的额外开销。
  • 劣势
    • 复杂性:实现自定义迭代器需要更多的代码和对 Rust 迭代器机制的深入理解,相比使用标准迭代器更易出错。
    • 通用性差:标准迭代器适用于各种标准集合类型,自定义迭代器通常仅适用于特定数据结构,复用性低。