0Pricing
Learn Rust Coding · 课时

Iterator 特征

next 与惰性求值

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

什么是迭代器

迭代器是能够逐个生成一系列值的任何对象。在 Rust 中,迭代器是处理向量、范围和切片等集合的惯用方式。

整个概念建立在一个特征之上:Iterator。某个类型实现它后,您就能免费获得数十种实用方法。

Iterator 特征

Iterator 特征要求实现一个方法 next,并定义一个关联类型 Item:

  • type Item — 生成的值的类型
  • fn next(&mut self) -> Option<Self::Item> — 返回下一个值

只要还有值,它就会返回 Some(value);完成后则返回 None。

fn main() {
    let v = vec![10, 20, 30];
    let mut it = v.iter();
    println!("{:?}", it.next());
    println!("{:?}", it.next());
    println!("{:?}", it.next());
    println!("{:?}", it.next());
}

next 返回 Option

每次调用 next 都会推进迭代器,并向您提供一个 Option。Some 包装实际值;None 表示已到末尾。

请注意,next 接受 &mut self — 调用它会改变内部状态,因此下一次调用会返回不同的值。

fn main() {
    let mut it = (1..4).into_iter();
    while let Some(n) = it.next() {
        println!("got {}", n);
    }
    println!("done");
}

迭代器是惰性的

创建迭代器本身不会执行任何操作。在某个对象请求值之前,不会计算任何值。这称为惰性。

在下一个示例中,map 闭包从未运行,因为我们从未消耗这个迭代器。

fn main() {
    let nums = vec![1, 2, 3];
    let _doubled = nums.iter().map(|x| {
        println!("mapping {}", x);
        x * 2
    });
    println!("nothing printed above this line");
}

消耗迭代器会触发执行

要让惰性迭代器真正运行,您需要消耗它。for 循环是最简单的消耗方式:它会反复调用 next,直到得到 None。

现在,相同的 map 闭包会针对每个元素运行。

fn main() {
    let nums = vec![1, 2, 3];
    for x in nums.iter().map(|x| x * 2) {
        println!("value {}", x);
    }
}

三种迭代方式

集合提供了三种生成迭代器的方法:

  • iter() — 生成 &T(借用)
  • iter_mut() — 生成 &mut T(可变借用)
  • into_iter() — 生成 T(取得所有权)
fn main() {
    let mut v = vec![1, 2, 3];
    for x in v.iter_mut() {
        *x += 10;
    }
    println!("{:?}", v);
}

for 循环使用 into_iter

直接写出 for x in collection 时,Rust 会调用 into_iter(),从而消耗该集合。

循环结束后,您无法再次使用 v,因为它已被移动到迭代器中。

fn main() {
    let v = vec![String::from("a"), String::from("b")];
    for s in v {
        println!("{}", s);
    }
    // v is no longer usable here
}

范围也是迭代器

像 0..5 这样的范围本身就是迭代器,会生成 0, 1, 2, 3, 4。结束位置是排他的。使用 0..=5 可创建包含结束值的范围。

范围非常适合执行计数循环,无需手动跟踪索引。

fn main() {
    for i in 0..5 {
        print!("{} ", i);
    }
    println!();
    for i in 1..=3 {
        print!("{} ", i);
    }
    println!();
}

count:简单的消耗器

count 会消耗整个迭代器,并返回它生成的项目数量。它是众多消耗型适配器之一。

由于它会消耗迭代器,因此之后无法再次使用该迭代器。

fn main() {
    let total = (1..=100).count();
    println!("there are {} numbers", total);
}

sum:折叠为一个值

sum 会将所有项目相加,并返回一个值。您通常需要标注目标类型,以便 Rust 知道应生成什么。

这比手动编写累加器循环更加简洁明了。

fn main() {
    let total: i32 = (1..=5).sum();
    println!("sum is {}", total);
}

迭代器为何重要

迭代器为您提供了可组合性:将小型操作串联起来,组成清晰的处理流水线。它们还是零成本的——编译器会将其优化得和手写循环一样快。

掌握 next、惰性求值和消费,是学习后续所有内容的基础。

快速检查

测试您对迭代器特征的理解。

回顾

您已经学会了 Rust 迭代器的核心知识:

  • Iterator 特征只需要 next 和一个 Item 类型
  • next 会先返回 Some(value),然后返回 None
  • 迭代器是惰性的——在被消费之前不会执行任何操作
  • iter、iter_mut 和 into_iter 控制借用与所有权
  • for、count 和 sum 等消费者会驱动实际处理

常见问题解答

「Iterator 特征」课时是免费的吗?

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

「Iterator 特征」这节课中我会学到什么?

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

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

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

「Iterator 特征」课时需要多长时间?

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

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

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

此课程中的所有课时

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