在自定义类型上实现迭代器,如 impl Iterator for ReadDir
,也可以通过方法返回一个实现迭代器的类型(惯例是 Iter/IterMut/IntoIter)对象,惯例的方法名是:
iter(&self)
: 返回的类型惯例是 Iter,迭代返回的是 &T 类型;iter_mut(&mut self)
: 返回的类型惯例是 IterMut,迭代返回的是 &mut T 类型;into_iter(self)
: 返回的迭代器对象惯例类型是 IntoIter,转移了被迭代对象的所有权,迭代返回的是 T 类型;
如果类型实现了 std::iter::IntoIterator trait
则称为可迭代对象,即可以使用
for-in 表达式来迭代对象,也可以给被迭代对象加 &obj 或 &mut obj 来让 for-in 使用
iter/iter_mut() 返回的对象:
Rust 为实现 Iterator 的类型自动实现了 IntoIterator
:
#[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")]
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator> IntoIterator for I {
type Item = I::Item;
type IntoIter = I;
#[inline]
fn into_iter(self) -> I {
self
}
}
Vec<T>,[T; N],HashSet<T>
等实现了 IntoIterator
:
let mut v = vec![1, 2, 3];
for i in &v {
println!("{i}")
}
for in in &mut v {
println!("{i}")
}
for i in v { // v 被消耗
println!("{i}");
}
// v 不可再访问
如果直接在自定义类型上实现迭代器,如 impl Iterator for ReadDir
,则在 ReadDir 上调用一些 self 迭代器方法,如 readDir.take(3) 后,readDir 将失效。但是如果在
iter()/iter_mut() 返回的迭代器对象上调用 take() 方法,消耗的是迭代器本身,原对象还可以正常访问. into_iter() 会转移对象所有权,迭代也是直接返回元素本身,所以 take() 返回并消耗对象。
消耗迭代器的方式:
- for-in 循环: 需要对象实现 std::iter::IntoIterator trait;
- Iterator trait 定义的泛型方法大部分都是消耗 self,如 iter.sum()/map() 等,所以
调用后迭代器对象所有权发生转移
for-in 使用 IntoIter 迭代器,它会消耗被迭代对象的元素。可以通过 &obj 或 &mut obj 来使用 Iter 或 IterMut 迭代器;
let mut array = [1, 2, 3];
// IntoIter
for n in array { // n 为 uint
println!(n);
}
// 迭代后 array 不能再使用
// Iter
for n in &array { // n 为 &uint
println!(n);
}
// 迭代后 array 可以使用
// IterMut
for n in &mut array { // n 为 &mut uint
println!(n);
}
当迭代它们的引用类型时,返回的元素是引用类型,这是由于标准库 为 &HashMap/&mut HashMap/ HashMap 类型分别实现
了对应的 IntoIterator:
// https://doc.rust-lang.org/src/std/collections/hash/map.rs.html#2173-2182
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> {
type Item = (&'a K, &'a V);
// Iter 是 HashMap 定义的实现 Iterator trait 的类型
type IntoIter = Iter<'a, K, V>;
#[inline]
#[rustc_lint_query_instability]
fn into_iter(self) -> Iter<'a, K, V> {
self.iter()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S> {
type Item = (&'a K, &'a mut V);
// IterMut 是 HashMap 定义的实现 Iterator trait 的类型
type IntoIter = IterMut<'a, K, V>;
#[inline]
#[rustc_lint_query_instability]
fn into_iter(self) -> IterMut<'a, K, V> {
self.iter_mut()
}
}
for-in 迭代器也可以使用 pattern match 来析构迭代变量:
let mut array = [(1, 2, 3), (4, 5, 6)];
for (a, b, &c) in &array { // &c 匹配引用类型,所以 c 是引用类型
println!("{} {} {}", a, b, *c);
}
迭代器适配器(iterator adaptor)是 Iterator trait
的方法,它一般会消耗旧 Iterator
(这些适配器方法的输入绝大大部分是 self)并返回新的 Iterator。Iterator 都是 lazy 的,必须被消耗时才能执行,如调用 collect() ;
- collect() 返回的是一个实现了 FromIterator<Self::Item> trait 的对象;
- 标准库的容器类型,如 Vec/HastSet/HashMap 都实现了 FromIterator trait,可以从可迭代对象生成容器元素。
#[derive(PartialEq, Debug)]
struct Shoe {
size: u32,
style: String,
}
// 由于返回一个 Vec<Shoe> ,所以需要 into_iter() 返回的 IntoIter 迭代器。
fn shoes_in_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
shoes.into_iter().filter(|s| s.size == shoe_size).collect()
}
// Vec<T> 实现了 FromIterator<T> trait, 所以 collect() 方法可以返回该类型对象:
let v1: Vec<i32> = vec![1, 2, 3];
// iter() 返回 &32, 所以最终 collect() 返回的是 &i32.
let v2: Vec<&i32> = v1.iter().map(|x| x + 1).collect();
assert_eq!(v2, vec![2, 3, 4]);
// 另一个例子
impl Config {
// Vec<String> 实现了该 trait
pub fn build(mut args: impl Iterator<Item = String>,)
-> Result<Config, &'static str> {
args.next();
let query = match args.next() {
Some(arg) => arg,
None => return Err("Didn't get a query string"),
};
let file_path = match args.next() {
Some(arg) => arg,
None => return Err("Didn't get a file path"),
};
let ignore_case = env::var("IGNORE_CASE").is_ok();
Ok(Config {
query,
file_path,
ignore_case,
})
}
}
fn main() {
let config = Config::build(env::args()).unwrap_or_else(|err| {
eprintln!("Problem parsing arguments: {err}");
process::exit(1);
});
// --snip--
}
Option/Result 是 enum 类型,也支持迭代(实现了 IntoIterator),效果为 1 个或 0 个元素:
- filter_map(): 先执行 map 返回 Option,然后再 filter 出结果为 Some 的元素,类似于这种双功能的方法,都是先执行后一个功能,对结果再执行前一个功能。例如 flat_map() 先对元素进行 map F 操作,F 返回一个迭代器,然后对各 map 结果迭代器进行 flat 操作。
let turing = Some("Turing");
let mut logicians = vec!["Curry", "Kleene", "Markov"];
// Option 实现了 IntoIterator, 因此可以传入 .extend() 方法中;
logicians.extend(turing);
// 也可以传入 chain() 方法中
let turing = Some("Turing");
let logicians = vec!["Curry", "Kleene", "Markov"];
for logician in logicians.iter().chain(turing.iter()) {
println!("{logician} is a logician");
}
Rust range 表达式是一系列支持迭代的 std::ops::RangeXX struct 类型的语法糖:
1..2; // std::ops::Range
3..; // std::ops::RangeFrom
..4; // std::ops::RangeTo
..; // std::ops::RangeFull
5..=6; // std::ops::RangeInclusive
..=7; // std::ops::RangeToInclusive
let x = std::ops::Range {start: 0, end: 10};
let y = 0..10;
assert_eq!(x, y);
1 迭代器方法 #
// Required method
fn next(&mut self) -> Option<Self::Item>;
// 返回下一个 N 个元素的数组,N 的数量可以指定或推导
fn next_chunk<const N: usize>( &mut self )
-> Result<[Self::Item; N], IntoIter<Self::Item, N>> where Self: Sized
let mut iter = "lorem".chars();
// N is inferred as 2
assert_eq!(iter.next_chunk().unwrap(), ['l', 'o']);
// N is inferred as 3
assert_eq!(iter.next_chunk().unwrap(), ['r', 'e', 'm']);
// N is explicitly 4
assert_eq!(iter.next_chunk::<4>().unwrap_err().as_slice(), &[]);
let quote = "not all those who wander are lost";
// 自动推导
let [first, second, third] = quote.split_whitespace().next_chunk().unwrap();
assert_eq!(first, "not");
assert_eq!(second, "all");
assert_eq!(third, "those");
// 返回迭代器中剩下元素的下界和上界
fn size_hint(&self) -> (usize, Option<usize>) { ... }
// 返回迭代器中元素数量(消耗)
fn count(self) -> usize where Self: Sized { ... }
// 返回最后一个元素(消耗)
fn last(self) -> Option<Self::Item> where Self: Sized { ... }
// 前进迭代器 n 个元素
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { ... }
#![feature(iter_advance_by)]
use std::num::NonZeroUsize;
let a = [1, 2, 3, 4];
let mut iter = a.iter();
assert_eq!(iter.advance_by(2), Ok(()));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.advance_by(0), Ok(()));
// only `&4` was skipped
assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(99).unwrap()));
// 返回第 n 个元素(0 开始,不消耗迭代器所有权,可以多次调用)
fn nth(&mut self, n: usize) -> Option<Self::Item> { ... }
let a = [1, 2, 3];
let mut iter = a.iter();
assert_eq!(iter.nth(1), Some(&2));
// 调用 nth(n) 多次并不重复返回
assert_eq!(iter.nth(1), None);
assert_eq!(iter.nth(10), None);
// 返回一个新的迭代器,每次返回原始迭代器的 +step 后的元素
fn step_by(self, step: usize) -> StepBy<Self> where Self: Sized { ... }
let a = [0, 1, 2, 3, 4, 5];
let mut iter = a.iter().step_by(2);
assert_eq!(iter.next(), Some(&0)); // 第一个元素
assert_eq!(iter.next(), Some(&2)); // +2
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), None);
// 将两个迭代器合并为一个,先迭代自身再迭代传入的 other, 迭代的元素 Item 类型要一致
fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where Self: Sized, U: IntoIterator<Item = Self::Item>
let a1 = [1, 2, 3];
let a2 = [4, 5, 6];
let mut iter = a1.iter().chain(a2.iter());
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), Some(&5));
assert_eq!(iter.next(), Some(&6));
assert_eq!(iter.next(), None);
// 从两个迭代器返回一个新的迭代器,每次各返回一个值,直到某个迭代器完成
fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where Self: Sized, U: IntoIterator
let a1 = [1, 2, 3];
let a2 = [4, 5, 6];
let mut iter = a1.iter().zip(a2.iter());
assert_eq!(iter.next(), Some((&1, &4)));
assert_eq!(iter.next(), Some((&2, &5)));
assert_eq!(iter.next(), Some((&3, &6)));
assert_eq!(iter.next(), None);
let enumerate: Vec<_> = "foo".chars().enumerate().collect();
let zipper: Vec<_> = (0..).zip("foo".chars()).collect();
assert_eq!((0, 'f'), enumerate[0]);
assert_eq!((0, 'f'), zipper[0]);
assert_eq!((1, 'o'), enumerate[1]);
assert_eq!((1, 'o'), zipper[1]);
assert_eq!((2, 'o'), enumerate[2]);
assert_eq!((2, 'o'), zipper[2]);
// 在迭代器元素间插入一个 separator 元素(需要实现 Clone)
fn intersperse(self, separator: Self::Item) -> Intersperse<Self> where Self: Sized, Self::Item: Clone
#![feature(iter_intersperse)]
let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
assert_eq!(hello, "Hello World !");
let mut a = [0, 1, 2].iter().intersperse(&100);
assert_eq!(a.next(), Some(&0)); // The first element from `a`.
assert_eq!(a.next(), Some(&100)); // The separator.
assert_eq!(a.next(), Some(&1)); // The next element from `a`.
assert_eq!(a.next(), Some(&100)); // The separator.
assert_eq!(a.next(), Some(&2)); // The last element from `a`.
assert_eq!(a.next(), None); // The iterator is finished.
// 使用指定的闭包函数插入分隔符
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> where Self: Sized, G: FnMut() -> Self::Item
// 使用指定的闭包函数来处理每一个元素(消耗迭代器),结果形成另一个可迭代对象
fn map<B, F>(self, f: F) -> Map<Self, F> where Self: Sized, F: FnMut(Self::Item) -> B
let a = [1, 2, 3];
let mut iter = a.iter().map(|x| 2 * x);
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), Some(6));
assert_eq!(iter.next(), None);
// 对每一个元素调用指定的闭包函数(消耗迭代器)
fn for_each<F>(self, f: F) where Self: Sized, F: FnMut(Self::Item) { ... }
use std::sync::mpsc::channel;
let (tx, rx) = channel();
(0..5).map(|x| x * 2 + 1).for_each(move |x| tx.send(x).unwrap());
let v: Vec<_> = rx.iter().collect();
assert_eq!(v, vec![1, 3, 5, 7, 9]);
// 使用 predicate 过滤元素,返回为 true 的元素的迭代器(predicate 的参数是元素的借用)
fn filter<P>(self, predicate: P) -> Filter<Self, P> where Self: Sized, P: FnMut(&Self::Item) -> bool
let a = [0, 1, 2];
// **x 需要两个 *,和 map() 不同,filter 闭包函数的参数是 &T 类型。
let mut iter = a.iter().filter(|x| **x > 1);
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
let a = [0, 1, 2];
let mut iter = a.iter().filter(|&x| *x > 1); // both & and *
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
let a = [0, 1, 2];
let mut iter = a.iter().filter(|&&x| x > 1); // two &s
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
// 对迭代元素值先执行 f 闭包(map),返回结果为 Some(value) 的 value(filter)迭代器
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where Self: Sized, F: FnMut(Self::Item) -> Option<B>
let a = ["1", "two", "NaN", "four", "5"];
let mut iter = a.iter().filter_map(|s| s.parse().ok()); // Result 的 ok() 方法返回 Option
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
// 等效为 filter().map()
let a = ["1", "two", "NaN", "four", "5"];
let mut iter = a.iter().map(|s| s.parse()).filter(|s| s.is_ok()).map(|s| s.unwrap());
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
// 返回 (i, value) 的迭代器,i 的类型为 usize
fn enumerate(self) -> Enumerate<Self> where Self: Sized { ... }
let a = ['a', 'b', 'c'];
let mut iter = a.iter().enumerate();
assert_eq!(iter.next(), Some((0, &'a')));
assert_eq!(iter.next(), Some((1, &'b')));
assert_eq!(iter.next(), Some((2, &'c')));
assert_eq!(iter.next(), None);
// 返回一个迭代器,它的 peek/peek_mut() 返回下一个迭代元素,但是并不消费迭代元素
fn peekable(self) -> Peekable<Self> where Self: Sized
let xs = [1, 2, 3];
let mut iter = xs.iter().peekable();
// peek() lets us see into the future
assert_eq!(iter.peek(), Some(&&1));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
// we can peek() multiple times, the iterator won't advance
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.next(), Some(&3));
// after the iterator is finished, so is peek()
assert_eq!(iter.peek(), None);
assert_eq!(iter.next(), None);
// 迭代时一直忽略元素,直到 predicte 返回 false(包含返回 false 的元素)
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where Self: Sized, P: FnMut(&Self::Item) -> bool
let a = [-1i32, 0, 1];
let mut iter = a.iter().skip_while(|x| x.is_negative());
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), None);
// 注意:一旦 predicate 返回 false,后续就不再对元素进行判断
let a = [-1, 0, 1, -2];
let mut iter = a.iter().skip_while(|x| **x < 0);
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
// while this would have been false, since we already got a false,
// skip_while() isn't used any more
assert_eq!(iter.next(), Some(&-2));
assert_eq!(iter.next(), None);
// 当 predicate 返回 true 时,返回元素。但是一旦返回 false,则忽略后续的元素。
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where Self: Sized, P: FnMut(&Self::Item) -> bool
let a = [-1i32, 0, 1];
let mut iter = a.iter().take_while(|x| x.is_negative());
assert_eq!(iter.next(), Some(&-1));
assert_eq!(iter.next(), None);
// 一旦 predicate 返回 false,就不再返回后续的元素。
let a = [-1, 0, 1, -2];
let mut iter = a.iter().take_while(|x| **x < 0);
assert_eq!(iter.next(), Some(&-1));
// We have more elements that are less than zero, but since we already
// got a false, take_while() isn't used any more
assert_eq!(iter.next(), None);
// 持续对每个元素应用 predicate,直到它返回 None(predicate 返回 some 时继续)
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where Self: Sized, P: FnMut(Self::Item) -> Option<B>
let a = [-1i32, 4, 0, 1];
let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x));
assert_eq!(iter.next(), Some(-16));
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), None);
// 忽略前 n 个元素
fn skip(self, n: usize) -> Skip<Self> where Self: Sized { ... }
let a = [1, 2, 3];
let mut iter = a.iter().skip(2);
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
// 只获取前 n 个元素
fn take(self, n: usize) -> Take<Self> where Self: Sized { ... }
let v = [1, 2];
let mut iter = v.into_iter().take(5);
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
// 返回一个迭代器,每次迭代返回 f 闭包执行的结果 Some,当闭包 f 返回 None 时停止迭代
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option<B>
let a = [1, 2, 3, 4];
let mut iter = a.iter().scan(1, |state, &x| {
// each iteration, we'll multiply the state by the element ...
*state = *state * x;
// ... and terminate if the state exceeds 6
if *state > 6 {
return None;
}
// ... else yield the negation of the state
Some(-*state)
});
assert_eq!(iter.next(), Some(-1));
assert_eq!(iter.next(), Some(-2));
assert_eq!(iter.next(), Some(-6));
assert_eq!(iter.next(), None);
// 先对元素进行 map F 操作,F 返回一个迭代器,然后对各 map 结果迭代器进行 flat
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where Self: Sized, U: IntoIterator, F: FnMut(Self::Item) -> U
let words = ["alpha", "beta", "gamma"];
// chars() returns an iterator
let merged: String = words.iter().flat_map(|s| s.chars()).collect();
assert_eq!(merged, "alphabetagamma");
// 返回一个将可迭代元素打平的迭代器
fn flatten(self) -> Flatten<Self> where Self: Sized, Self::Item: IntoIterator
let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
let flattened = data.into_iter().flatten().collect::<Vec<u8>>();
assert_eq!(flattened, &[1, 2, 3, 4, 5, 6]);
// Option/Result 也是可迭代的,可以使用 flatten() 来过滤掉 None 和 Err
let options = vec![Some(123), Some(321), None, Some(231)];
let flattened_options: Vec<_> = options.into_iter().flatten().collect();
assert_eq!(flattened_options, vec![123, 321, 231]);
let results = vec![Ok(123), Ok(321), Err(456), Ok(231)];
let flattened_results: Vec<_> = results.into_iter().flatten().collect();
assert_eq!(flattened_results, vec![123, 321, 231]);
// flatten 只会打平一级
let d3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]];
let d2 = d3.iter().flatten().collect::<Vec<_>>();
assert_eq!(d2, [&[1, 2], &[3, 4], &[5, 6], &[7, 8]]);
let d1 = d3.iter().flatten().flatten().collect::<Vec<_>>();
assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]);
// 先将元素按照 N 分组 window(window 间元素有重合),然后再对每个 window 的元素执行 f
// 闭包,如果元素少于 N 则返回空迭代器
// 闭包的参数类型是数组引用
fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N> where Self: Sized, F: FnMut(&[Self::Item; N]) -> R
#![feature(iter_map_windows)]
let strings = "abcd".chars()
.map_windows(|[x, y]| format!("{}+{}", x, y)) // &['a', 'b'], &['b', 'c'] and &['c', 'd']
.collect::<Vec<String>>();
assert_eq!(strings, vec!["a+b", "b+c", "c+d"]);
#![feature(iter_map_windows)]
let mut it = [0.5, 1.0, 3.5, 3.0, 8.5, 8.5, f32::NAN].iter()
.map_windows(|[a, b]| a <= b);
assert_eq!(it.next(), Some(true)); // 0.5 <= 1.0
assert_eq!(it.next(), Some(true)); // 1.0 <= 3.5
assert_eq!(it.next(), Some(false)); // 3.5 <= 3.0
assert_eq!(it.next(), Some(true)); // 3.0 <= 8.5
assert_eq!(it.next(), Some(true)); // 8.5 <= 8.5
assert_eq!(it.next(), Some(false)); // 8.5 <= NAN
assert_eq!(it.next(), None);
// 返回一个新迭代器,终止于原迭代器返回的第一个 None,用于防止原迭代器不规范的实现
fn fuse(self) -> Fuse<Self> where Self: Sized
// 对迭代的每一个元素执行闭包操作
fn inspect<F>(self, f: F) -> Inspect<Self, F> where Self: Sized, F: FnMut(&Self::Item)
// let's add some inspect() calls to investigate what's happening
let sum = a.iter()
.cloned()
.inspect(|x| println!("about to filter: {x}"))
.filter(|x| x % 2 == 0)
.inspect(|x| println!("made it through filter: {x}"))
.fold(0, |sum, i| sum + i);
println!("{sum}");
// borrow 但不转移 Self,迭代器可以继续使用
fn by_ref(&mut self) -> &mut Self where Self: Sized
let mut words = ["hello", "world", "of", "Rust"].into_iter();
// Take the first two words.
let hello_world: Vec<_> = words.by_ref().take(2).collect(); // 不转移 words
assert_eq!(hello_world, vec!["hello", "world"]);
// Collect the rest of the words. We can only do this because we used `by_ref` earlier.
let of_rust: Vec<_> = words.collect(); // words 还可以继续使用
assert_eq!(of_rust vec!["of", "Rust"]);
// 使用 B 的 FromIterator trait 来从自身迭代器元素生成 B 类型对象
fn collect<B>(self) -> B where B: FromIterator<Self::Item>, Self: Sized
let doubled: Vec<i32> = a.iter() .map(|&x| x * 2) .collect();
assert_eq!(vec![2, 4, 6], doubled);
let a = [1, 2, 3];
let doubled = a.iter().map(|x| x * 2).collect::<Vec<i32>>();
assert_eq!(vec![2, 4, 6], doubled);
// 检查 Result 列表
let results = [Ok(1), Err("nope"), Ok(3), Err("bad")];
let result: Result<Vec<_>, &str> = results.iter().cloned().collect();
// gives us the first error
assert_eq!(Err("nope"), result);
let results = [Ok(1), Ok(3)];
let result: Result<Vec<_>, &str> = results.iter().cloned().collect();
// gives us the list of answers
assert_eq!(Ok(vec![1, 3]), result);
// 允许失败的 collect,主要用于将迭代元素是 Option<T> 转换为 Option<Collector<T>> 类型
fn try_collect<B>( &mut self ) -> ::TryType where Self: Sized, Self::Item: Try, <Self::Item as Try>::Residual: Residual<B>, B: FromIterator<<Self::Item as Try>::Output>
#![feature(iterator_try_collect)]
let u = vec![Some(1), Some(2), Some(3)];
let v = u.into_iter().try_collect::<Vec<i32>>();
assert_eq!(v, Some(vec![1, 2, 3]));
// 将 Self 迭代的元素添加到传入的 collection 中
fn collect_into<E>(self, collection: &mut E) -> &mut E where E: Extend<Self::Item>, Self: Sized
#![feature(iter_collect_into)]
let a = [1, 2, 3];
let mut vec: Vec::<i32> = vec![0, 1];
a.iter().map(|&x| x * 2).collect_into(&mut vec);
a.iter().map(|&x| x * 10).collect_into(&mut vec);
assert_eq!(vec, vec![0, 1, 2, 4, 6, 10, 20, 30]);
// 使用 f 将迭代器元素分两组,分别为返回 true/false 的元素
fn partition<B, F>(self, f: F) -> (B, B) where Self: Sized, B: Default + Extend<Self::Item>, F: FnMut(&Self::Item) -> bool
let a = [1, 2, 3];
let (even, odd): (Vec<_>, Vec<_>) = a
.into_iter()
.partition(|n| n % 2 == 0);
assert_eq!(even, vec![2]);
assert_eq!(odd, vec![1, 3]);
// 原地修改 self,前一半部分为 true,后一半为 false,返回 true 元素数量
fn partition_in_place<'a, T, P>(self, predicate: P) -> usize where T: 'a, Self: Sized + DoubleEndedIterator<Item = &'a mut T>, P: FnMut(&T) -> bool
#![feature(iter_partition_in_place)]
let mut a = [1, 2, 3, 4, 5, 6, 7];
// Partition in-place between evens and odds
let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);
assert_eq!(i, 3);
assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens
assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
// 返回 self 是否按照 predicate 排序
fn is_partitioned<P>(self, predicate: P) -> bool where Self: Sized, P: FnMut(Self::Item) -> bool
#![feature(iter_is_partitioned)]
assert!("Iterator".chars().is_partitioned(char::is_uppercase));
assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>
fn try_for_each<F, R>(&mut self, f: F) -> R where Self: Sized, F: FnMut(Self::Item) -> R, R: Try<Output = ()>
// 将迭代器值按照 F 进行聚合,同时传入初始值,返回最后的结果
fn fold<B, F>(self, init: B, f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B { ... }
let a = [1, 2, 3];
// the sum of all of the elements of the array
let sum = a.iter().fold(0, |acc, x| acc + x);
assert_eq!(sum, 6);
// 和 fold 类似,但是使用第一个值作为初始值
fn reduce<F>(self, f: F) -> Option<Self::Item> where Self: Sized, F: FnMut(Self::Item, Self::Item) -> Self::Item
fn try_reduce<F, R>( &mut self, f: F ) -> >::TryType where Self: Sized, F: FnMut(Self::Item, Self::Item) -> R, R: Try<Output = Self::Item>, <R as Try>::Residual: Residual<Option<Self::Item>>
let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap();
assert_eq!(reduced, 45);
// Which is equivalent to doing it with `fold`:
let folded: i32 = (1..10).fold(0, |acc, e| acc + e);
assert_eq!(reduced, folded);
// 迭代的所有元素满足 f
fn all<F>(&mut self, f: F) -> bool where Self: Sized, F: FnMut(Self::Item) -> bool { ... }
// 迭代的任一元素满足 f
fn any<F>(&mut self, f: F) -> bool where Self: Sized, F: FnMut(Self::Item) -> bool { ... }
// 返回 predicate 为 true 的第一个元素或 None;对比:position() 返回元素的 index
fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where Self: Sized, P: FnMut(&Self::Item) -> bool
let a = [1, 2, 3];
let mut iter = a.iter();
assert_eq!(iter.find(|&&x| x == 2), Some(&2));
// we can still use `iter`, as there are more elements.
assert_eq!(iter.next(), Some(&3));
// 对迭代器元素执行 f,返回第一个结果为 Some(B) 的 Option<B>,等效于 iter.filter_map(f).next().
fn find_map<B, F>(&mut self, f: F) -> Option<B> where Self: Sized, F: FnMut(Self::Item) -> Option<B>
let a = ["lol", "NaN", "2", "5"];
let first_number = a.iter().find_map(|s| s.parse().ok());
assert_eq!(first_number, Some(2));
fn try_find<F, R>( &mut self, f: F ) -> >::TryType where Self: Sized, F: FnMut(&Self::Item) -> R, R: Try<Output = bool>, <R as Try>::Residual: Residual<Option<Self::Item>> { ... }
// 查找满足 predicate 的元素,返回它的 index。对比:find() 返回元素本身。
fn position<P>(&mut self, predicate: P) -> Option<usize> where Self: Sized, P: FnMut(Self::Item) -> bool
fn rposition<P>(&mut self, predicate: P) -> Option<usize> where P: FnMut(Self::Item) -> bool, Self: Sized + ExactSizeIterator + DoubleEndedIterator
let a = [1, 2, 3];
assert_eq!(a.iter().position(|&x| x == 2), Some(1));
assert_eq!(a.iter().position(|&x| x == 5), None);
fn max(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
fn min(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
// 根据 f 闭包返回的结果来找最大值
fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where B: Ord, Self: Sized, F: FnMut(&Self::Item) -> B
let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10);
// 根据 compare 函数的返回值来找最大值
fn max_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where B: Ord, Self: Sized, F: FnMut(&Self::Item) -> B
fn min_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering { ... }
// 返回迭代器的反向迭代器
fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator
let a = [1, 2, 3];
let mut iter = a.iter().rev();
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), None);
// 迭代器迭代返回 (A, B), 然后返回两个分别是 A 、B 聚合后的对象。A,B
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where FromA: Default + Extend<A>, FromB: Default + Extend<B>, Self: Sized + Iterator<Item = (A, B)>
let a = [(1, 2), (3, 4), (5, 6)];
let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
assert_eq!(left, [1, 3, 5]);
assert_eq!(right, [2, 4, 6]);
// you can also unzip multiple nested tuples at once
let a = [(1, (2, 3)), (4, (5, 6))];
let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip();
assert_eq!(x, [1, 4]);
assert_eq!(y, [2, 5]);
assert_eq!(z, [3, 6]);
// 使用元素的 Copy 对象来返回一个新的迭代器,特别适合从 &T 返回 T
fn copied<'a, T>(self) -> Copied<Self> where T: 'a + Copy, Self: Sized + Iterator<Item = &'a T>
let a = [1, 2, 3];
let v_copied: Vec<_> = a.iter().copied().collect();
// copied is the same as .map(|&x| x)
let v_map: Vec<_> = a.iter().map(|&x| x).collect();
assert_eq!(v_copied, vec![1, 2, 3]);
assert_eq!(v_map, vec![1, 2, 3]);
// 使用元素的 Clone 对象来返回一个新的迭代器,适合 从 &T 返回 T
fn cloned<'a, T>(self) -> Cloned<Self> where T: 'a + Clone, Self: Sized + Iterator<Item = &'a T>
let a = [1, 2, 3];
let v_cloned: Vec<_> = a.iter().cloned().collect();
// cloned is the same as .map(|&x| x), for integers
let v_map: Vec<_> = a.iter().map(|&x| x).collect();
assert_eq!(v_cloned, vec![1, 2, 3]);
assert_eq!(v_map, vec![1, 2, 3]);
// 循环返回迭代器的元素
fn cycle(self) -> Cycle<Self> where Self: Sized + Clone { ... }
let a = [1, 2, 3];
let mut it = a.iter().cycle();
assert_eq!(it.next(), Some(&1));
assert_eq!(it.next(), Some(&2));
assert_eq!(it.next(), Some(&3));
assert_eq!(it.next(), Some(&1));
assert_eq!(it.next(), Some(&2));
assert_eq!(it.next(), Some(&3));
assert_eq!(it.next(), Some(&1));
// 返回一个迭代器,每次迭代返回 N 个元素的数组。
fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N> where Self: Sized
// 返回元素的 sum,可能会 panic。Option/Result 也实现了 Sum
fn sum<S>(self) -> S where Self: Sized, S: Sum<Self::Item>
let a = [1, 2, 3];
let sum: i32 = a.iter().sum();
assert_eq!(sum, 6);
// 返回元素的乘积
fn product<P>(self) -> P where Self: Sized, P: Product<Self::Item>
fn factorial(n: u32) -> u32 {
(1..=n).product()
}
assert_eq!(factorial(0), 1);
assert_eq!(factorial(1), 1);
assert_eq!(factorial(5), 120);
// 比较两个迭代的各元素,元素必须实现 Ord trait(所以不能比较 float 值)
fn cmp<I>(self, other: I) -> Ordering where I: IntoIterator<Item = Self::Item>, Self::Item: Ord, Self: Sized
use std::cmp::Ordering;
assert_eq!([1].iter().cmp([1].iter()), Ordering::Equal);
assert_eq!([1].iter().cmp([1, 2].iter()), Ordering::Less);
assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
// 使用指定的 cmp 闭包函数来比较两个迭代器的元素
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where Self: Sized, I: IntoIterator, F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering
#![feature(iter_order_by)]
use std::cmp::Ordering;
let xs = [1, 2, 3, 4];
let ys = [1, 4, 9, 16];
assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| x.cmp(&y)), Ordering::Less);
assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal);
assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
// 与 cmp 相比,partial_cmp可以比较实现 PartialOrd trait 的值,如 float64
fn partial_cmp<I>(self, other: I) -> Option<Ordering> where I: IntoIterator, Self::Item: PartialOrd<<I as IntoIterator>::Item>, Self: Sized
fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where Self: Sized, I: IntoIterator, F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>
// 比较两个迭代器的元素,返回 ture/false
fn eq<I>(self, other: I) -> bool where I: IntoIterator, Self::Item: PartialEq<<I as IntoIterator>::Item>, Self: Sized { ... }
fn eq_by<I, F>(self, other: I, eq: F) -> bool where Self: Sized, I: IntoIterator, F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool { ... }
fn ne<I>(self, other: I) -> bool where I: IntoIterator, Self::Item: PartialEq<<I as IntoIterator>::Item>, Self: Sized { ... }
fn lt<I>(self, other: I) -> bool where I: IntoIterator, Self::Item: PartialOrd<<I as IntoIterator>::Item>, Self: Sized { ... }
fn le<I>(self, other: I) -> bool where I: IntoIterator, Self::Item: PartialOrd<<I as IntoIterator>::Item>, Self: Sized { ... }
fn gt<I>(self, other: I) -> bool where I: IntoIterator, Self::Item: PartialOrd<<I as IntoIterator>::Item>, Self: Sized { ... }
fn ge<I>(self, other: I) -> bool where I: IntoIterator, Self::Item: PartialOrd<<I as IntoIterator>::Item>, Self: Sized { ... }
// 判断迭代器的元素是否已排序
fn is_sorted(self) -> bool where Self: Sized, Self::Item: PartialOrd
fn is_sorted_by<F>(self, compare: F) -> bool where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> bool
fn is_sorted_by_key<F, K>(self, f: F) -> bool where Self: Sized, F: FnMut(Self::Item) -> K, K: PartialOrd
2 FromIterator #
从输入的迭代器 iter 创建一个 Self 对象(取决于实现该 Fromiterator 的对象类型), 输入的 iter 是IntoIterator 类型,所以会转移 iter 对象的所有权。
迭代器的泛型方法 collect<T>() 会自动调用 T::from_iter(self) 方法来生成 T 对象。
pub trait FromIterator<A>: Sized {
// Required method
fn from_iter<T>(iter: T) -> Self
where T: IntoIterator<Item = A>;
}
// 示例
let five_fives = std::iter::repeat(5).take(5);
let v = Vec::from_iter(five_fives);
assert_eq!(v, vec![5, 5, 5, 5, 5]);
// collect() 函数默认自动使用 FromIterator<A> trait
let five_fives = std::iter::repeat(5).take(5);
// 等效于:Vec<i32>::from_iter(five_fives)
let v: Vec<i32> = five_fives.collect();
assert_eq!(v, vec![5, 5, 5, 5, 5]);
实现 FromIterator<T>
的类型:
- impl<K, V> FromIterator<(K, V)> for BTreeMap<K, V>
- impl<T> FromIterator<T> for BTreeSet<T> where T: Ord,
- impl<T> FromIterator<T> for Vec<T>
impl FromIterator<char> for String
impl FromIterator<()> for ()
use std::io::*;
let data = vec![1, 2, 3, 4, 5];
let res: Result<()> = data.iter()
.map(|x| writeln!(stdout(), "{x}"))
.collect();
assert!(res.is_ok());
impl FromIterator<Box<str>> for String
impl FromIterator<OsString> for OsString
impl FromIterator<String> for String
impl<'a> FromIterator<&'a char> for String
impl<'a> FromIterator<&'a str> for String
impl<'a> FromIterator<&'a OsStr> for OsString
impl<'a> FromIterator<Cow<'a, str>> for String
impl<'a> FromIterator<Cow<'a, OsStr>> for OsString
impl<'a> FromIterator<char> for Cow<'a, str>
impl<'a> FromIterator<String> for Cow<'a, str>
impl<'a, 'b> FromIterator<&'b str> for Cow<'a, str>
impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone
impl<A, E, V> FromIterator<Result<A, E>> for Result<V, E> where V: FromIterator<A>
impl<A, V> FromIterator<Option<A>> for Option<V> where V: FromIterator<A>
impl<I> FromIterator<I> for Box<[I]>
impl<K, V> FromIterator<(K, V)> for BTreeMap<K, V> where K: Ord
impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S> where K: Eq + Hash, S: BuildHasher + Default
impl<P: AsRef<Path>> FromIterator<P> for PathBuf
impl<T> FromIterator<T> for BTreeSet<T> where T: Ord
impl<T> FromIterator<T> for BinaryHeap<T> where T: Ord
impl<T> FromIterator<T> for LinkedList<T>
impl<T> FromIterator<T> for VecDeque<T>
impl<T> FromIterator<T> for Rc<[T]>
impl<T> FromIterator<T> for Arc<[T]>
impl<T> FromIterator<T> for Vec<T>
impl<T, S> FromIterator<T> for HashSet<T,S> where T: Eq + Hash, S: BuildHasher + Default
impl FromIterator<TokenStream> for TokenStream
impl FromIterator<TokenTree> for TokenStream