本文介绍 rust 迭代器有关的 trait: Iterator
和IntoIterator
, 以及可遍历类型返回不同遍历器的三个方法:
into_iter
返回 T, &T 或 &mut T 类型的 Iterator, IntoIterator
的接口
iter
返回 Iterator<&T>,非 trait 接口
iter_mut
返回 Iterator<&mut T>, 非 trait 接口
IntoIterator trait
首先看写下面代码, 我们能够使用 for 循环遍历 Vec 和 HashMap
//for循环Vec<T>
let names = vec!["Pascal", "Elvira", "Dominic", "Christoph"];
for name in names {
println!("{}", name);
}
//for循环遍历HashMap<K,V>
let mut book_reviews = HashMap::new();
book_reviews.insert(
"Search Inside Yourself".to_string(),
"A great book about meditation.".to_string(),
);
book_reviews.insert(
"Limitless".to_string(),
"Unleash the potential of your brain!".to_string(),
);
for review in book_reviews {
println!("{}: {}", review.0, review.1);
}
复制代码
这是因为 Vec 和 HashMap 实现IntoIterator
,称作可遍历类型
pub trait IntoIterator
where
<Self::IntoIter as Iterator>::Item == Self::Item,
{
type Item;
type IntoIter: Iterator;
fn into_iter(self) -> Self::IntoIter;
}
复制代码
上面例子的 Vec 的 for 循环用法类似这样的调用:
let iterator = (names).into_iter();
while let Some(name) = iterator.next() {
println!("{}", name);
}
复制代码
Vec 实现了三种不同形式的 IntoInterator:
impl<T> IntoIterator for Vec<T>
impl<'a, T> IntoIterator for &'a Vec<T>
impl<'a, T> IntoIterator for &'a mut Vec<T>
复制代码
根据被遍历对象的类型,for 循环会选择使用哪个into_iter
方法并获得不同类型的元素:
可遍历对象的共享引用返回共享引用的元素 &T
可遍历对象的可变引用返回可变引用的元素 &mut T
拥有所有权的可遍历对象返回值 T。注意:这个可遍历对象被转移所有权,从而被会 drop 掉。
impl<T> IntoIterator for Vec<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(mut self) -> IntoIter<T> { /* ... */ }
}
复制代码
Iterator trait
into_iter
方法返回的Iterator
是真正实现遍历的地方。next 方法返回 None 代表循环结束
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
复制代码
一般可遍历对象还专门提供两个非 trait 接口的方法:iter(&self)
和iter_mut(&mut self )
评论