定义
- 支持遍历序列中的每一项和决定序列何时结束的逻辑
- 创建迭代器是惰性的,在调用方法使用迭代器之前不会有任何效果
- 每个迭代器都实现了
iterator trait
,定义在标准库中
#[doc(notable_trait)]
#[lang = "iterator"]
#[rustc_diagnostic_item = "Iterator"]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub trait Iterator {
/// The type of the elements being iterated over.
#[rustc_diagnostic_item = "IteratorItem"]
#[stable(feature = "rust1", since = "1.0.0")]
type Item;
#[lang = "next"]
#[stable(feature = "rust1", since = "1.0.0")]
fn next(&mut self) -> Option<Self::Item>;
}
type Item
和Self::Item
这种用法叫做定义trait的关联类型next
是Iterator被要求实现的唯一一个方法,next
一次返回一个元素,当迭代器结束的时候,返回None
for in 遍历
fn main() {
let vec = vec![1, 2, 3, 4, 5];
let iter = vec.iter(); // 此刻不会对变量 vec 产生影响
for i in iter {
println!("{}",i)
}
}
next 遍历
迭代不可变引用
fn main() {
let vec = vec![1, 2];
let mut iter = vec.iter();
if let Some(val) = iter.next() {
println!("{}",val)
}
if let Some(val) = iter.next() {
println!("{}",val)
}
if let Some(val) = iter.next() {
println!("{}",val)
}else {
println!("{}","None")
}
}
迭代可变引用
- 原始数组必须是可变的
- 迭代器也要指定为可变的
fn main() {
let mut vec = vec![1, 2];
let mut iter = vec.iter_mut(); // 此刻不会对变量 vec 产生影响
if let Some(val) = iter.next() {
println!("{}", val);
*val = 3; // 解引用
}
if let Some(val) = iter.next() {
println!("{}", val);
*val = 4;
}
if let Some(val) = iter.next() {
println!("{}", val)
} else {
println!("{}", "None")
}
println!("{:?}", vec) // [3, 4]
}
消费适配器
fn main() {
let vec = vec![1, 2, 3];
let total: i32 = vec.iter().sum();
println!("{}", total);
}
迭代适配器:类似于Java中的stream式操作
fn main() {
let vec = vec![1, 2, 3];
// 将数组中的每个元素都加1
let val: Vec<i32> = vec.iter().map(|x| x + 1).collect();
println!("{:?}", val);
// 过滤出数组中大于2的值
let val: Vec<i32> = vec.into_iter().filter(|x| *x > 2).collect();
println!("{:?}", val);
}
自定义迭代器
struct Counter {
count: i32,
}
impl Iterator for Counter {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < 3 {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
fn main() {
let mut counter = Counter { count: 0 };
for _ in (0..=3) {
if let Some(val) = counter.next() {
println!("{}", val);
} else {
println!("{}", "end");
}
}
}