本文介绍 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 )
评论