迭代器作为输入
以下代码
fn func1(data: &[u32]) {}
如果我们只需要迭代 data
中的数据, 那么可以将参数改写成 IntoIterator
使该函数更通用:
fn func1(data: impl IntoIterator<Item=u32>) {}
构造和扩展集合
如果你有一个集合类型, 那么你应该考虑为其实现 FromIterator
和 Extend
trait.
FromIterator
允许您从迭代器构造一个集合类型的实例, 这是通过 collect
方法实现. Extend
允许您添加一个迭代器的内容到一个集合中, 通过 extend
方法.
// collect
let a = [1, 2, 3];
let doubled: Vec<i32> = a.iter()
.map(|&x| x * 2)
.collect();
assert_eq!(vec![2, 4, 6], doubled);
// extend
let mut message = String::from("abc");
message.extend(['d', 'e', 'f'].iter());
assert_eq!("abcdef", &message);
为集合类型添加 Iterator trait
如果我们有一个类型包含了某些实例的集合, 那么我们可以为该类型添加迭代功能. 拥有迭代功能的类型我们可以称之为 iterable
.
iterator
类型实现了Iterator
iterable
类型实现了IntoIterator
3 种迭代类型
在 Rust
中, 你有三种迭代方法 - 通过值, 通过引用和通过唯一引用. 它们在 for
循环中可以表达为:
for item in collection // 值
for item in &collection // 引用
for item in &mut collection // 唯一引用
上述调用相当于 Rust
中的
// 通过值
let mut iterator = collection.into_iter();
while let Some(item) = iterator.next() {}
// 通过引用
let mut iterator = (& collection).into_iter();
while let Some(item) = iterator.next() {}
// 通过唯一引用
let mut iterator = (&mut collection).into_iter();
while let Some(item) = iterator.next() {}
- 许多集合类型同时实现了
iter()
和iter_mut()
方法. 它们等同于上述例子中的引用和唯一引用. - 不是所有的集合都同时实现这三种迭代. 有时候, 对通过唯一引用进行迭代是无效的. 例如, 我们不能对
HashMap
的key
进行唯一引用迭代, 因为修改一个key
值会破坏HashMap
的数据结构的一致性. 但是我们可以迭代key-value
对, 其中key
是引用,value
是唯一引用. 详见HashMap.iter_mut
.