0Pricing
Learn Rust Coding · 课时

自定义迭代器

实现 Iterator

自定义迭代器 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。

创建您自己的迭代器

您不受限于内置迭代器。通过为自己的类型实现 Iterator 特征,它就能免费获得所有适配器和消费者。

您只需提供 Item 类型和一个 next 方法。

Counter 结构体

先创建一个保存迭代器状态的结构体。简单的计数器只需要一个当前值。

struct Counter {
    count: u32,
}

fn main() {
    let c = Counter { count: 0 };
    println!("start at {}", c.count);
}

实现 next

为该结构体实现 Iterator。设置 type Item,然后编写 next 来推进状态:在达到停止条件之前返回 Some,之后返回 None。

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

fn main() {
    let mut c = Counter { count: 0 };
    println!("{:?}", c.next());
    println!("{:?}", c.next());
}

在 for 循环中使用

一旦存在 next,您的类型就可以像任何标准迭代器一样在 for 循环中使用。

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    for n in (Counter { count: 0 }) {
        print!("{} ", n);
    }
    println!();
}

免费获得适配器和消费者

由于您只实现了一个方法,整个迭代器工具箱现在都可以使用了。这里我们将配对的计数器值求平方后再求和。

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let total: u32 = Counter { count: 0 }.map(|x| x * 2).sum();
    println!("{}", total);
}

构造函数方法

添加一个 new 函数,这样用户就不必直接操作内部字段。这种方式更加整洁,也能让您将字段保持为私有。

struct Counter { count: u32 }

impl Counter {
    fn new() -> Counter { Counter { count: 0 } }
}

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 3 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let v: Vec<u32> = Counter::new().collect();
    println!("{:?}", v);
}

Fibonacci 迭代器

迭代器可以携带更丰富的状态。Fibonacci 生成器会保存最后两个值,并在每次调用 next 时更新它们。

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let current = self.a;
        self.a = self.b;
        self.b = current + self.b;
        Some(current)
    }
}

fn main() {
    let fib = Fib { a: 0, b: 1 };
    let seq: Vec<u64> = fib.take(8).collect();
    println!("{:?}", seq);
}

无限迭代器也没问题

Fibonacci 迭代器永远不会返回 None——它是无限的。这是安全的,因为惰性求值意味着只有在需要时才会生成值。使用 take 可以限制它的长度。

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let c = self.a;
        self.a = self.b;
        self.b = c + self.b;
        Some(c)
    }
}

fn main() {
    let big = Fib { a: 0, b: 1 }.nth(20);
    println!("{:?}", big);
}

遍历包装类型

您经常会在一个借用数据的辅助结构体上实现 Iterator。这里,一个步进器会从内部存储的范围中每隔一个数字生成一个值。

struct EvenUpTo { current: u32, max: u32 }

impl Iterator for EvenUpTo {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.current > self.max { return None; }
        let value = self.current;
        self.current += 2;
        Some(value)
    }
}

fn main() {
    let evens: Vec<u32> = (EvenUpTo { current: 0, max: 10 }).collect();
    println!("{:?}", evens);
}

为何要构建自定义迭代器

自定义迭代器可以让您在不分配完整集合的情况下流式生成值,表示无限或计算得出的序列,并为调用者提供熟悉且可组合的接口。

一个小小的 next 方法就能解锁整个生态系统。

设计建议

让状态保持精简,在结束时恰好返回一次 None(无限迭代器则永不返回),并避免在 next 中执行繁重操作,以便让惰性求值保持轻量。

快速检查

实现迭代器特征。

回顾

您已经构建了自定义迭代器:

  • 在结构体中保存状态,然后实现 impl Iterator
  • 定义 type Item 并编写 next
  • 立即免费获得适配器和消费者
  • 迭代器可以是有限的,也可以是无限的;使用 take 限制无限迭代器

常见问题解答

「自定义迭代器」课时是免费的吗?

是的 — 「自定义迭代器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。

「自定义迭代器」这节课中我会学到什么?

实现 Iterator 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Learn Rust Coding 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「自定义迭代器」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Learn Rust Coding 课中编写并运行代码吗?

能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Iterator 特征
  2. map、filter、collect
  3. 适配器与消费者
  4. 自定义迭代器
← 返回 Learn Rust Coding