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 反馈 — 无需本地设置。
此课程中的所有课时
- Iterator 特征
- map、filter、collect
- 适配器与消费者
- 自定义迭代器