[−][src]Function tao_of_rust::ch06::iters::iters
pub fn iters()
迭代器
Base usage: 自定义内部迭代器
trait InIterator<T: Copy> { fn each<F: Fn(T) -> T>(&mut self, f: F); } impl<T: Copy> InIterator<T> for Vec<T> { fn each<F: Fn(T) -> T>(&mut self, f: F) { let mut i = 0; while i < self.len() { self[i] = f(self[i]); i += 1; } } } fn main(){ let mut v = vec![1,2,3]; v.each(|i| i * 3); assert_eq!([3, 6, 9], &v[..3]); }Run
Base usage: 外部迭代器 for
fn main() { let v = vec![1, 2, 3, 4, 5]; for i in v { println!("{}", i); } }Run
Base usage: for循环的等价代码
fn main() { let v = vec![1, 2, 3, 4, 5]; { // 等价于for循环的scope let mut _iterator = v.into_iter(); loop { match _iterator.next() { Some(i) => { println!("{}", i); } None => break, } } } }Run
Base usage: 为自定义结构体实现Iterator
struct Counter { count: usize, } impl Iterator for Counter { type Item = usize; fn next(&mut self) -> Option<usize> { self.count += 1; if self.count < 6 { Some(self.count) } else { None } } } fn main() { let mut counter = Counter { count: 0 }; assert_eq!(Some(1), counter.next()); assert_eq!(Some(2), counter.next()); assert_eq!(Some(3), counter.next()); assert_eq!(Some(4), counter.next()); assert_eq!(Some(5), counter.next()); assert_eq!(None, counter.next()); }Run
Base usage: size_hint方法,可获取迭代器剩余长度的边界信息
fn main() { let a : [i32; 3]= [1, 2, 3]; let mut iter = a.iter(); assert_eq!((3, Some(3)), iter.size_hint()); iter.next(); assert_eq!((2, Some(2)), iter.size_hint()); }Run
Base usage: 切片实现了Iter和IterMut
fn main(){ let arr = [1, 2, 3, 4, 5]; for i in arr.iter() { println!("{:?}", i); } println!("{:?}", arr); }Run
Base usage: Map是Rust里最常见的迭代器适配器
此示例还包括了其他适配器
fn main() { let arr1 = [1, 2, 3, 4, 5]; let c1 = arr1.iter().map(|x| 2 * x).collect::<Vec<i32>>(); assert_eq!(&c1[..], [2, 4, 6, 8, 10]); let arr2 = ["1", "2", "3", "h"]; let c2 = arr2.iter().filter_map(|x| x.parse().ok()) .collect::<Vec<i32>>(); assert_eq!(&c2[..], [1,2,3]); let arr3 = ['a', 'b', 'c']; for (idx, val) in arr3.iter().enumerate() { println!("idx: {:?}, val: {}", idx, val.to_uppercase()); } }Run
Base usage: Rev 反向迭代器适配器
fn main() { 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); }Run
Base usage: next_back方法示意
fn main() { let numbers = vec![1, 2, 3, 4, 5, 6]; let mut iter = numbers.into_iter(); assert_eq!(Some(1), iter.next()); assert_eq!(Some(6), iter.next_back()); assert_eq!(Some(5), iter.next_back()); assert_eq!(Some(2), iter.next()); assert_eq!(Some(3), iter.next()); assert_eq!(Some(4), iter.next()); assert_eq!(None, iter.next()); assert_eq!(None, iter.next_back()); }Run
Base usage: 消费器any和fold示意
fn main() { let a = [1, 2, 3]; assert_eq!(a.iter().any(|&x| x != 2), true); let sum = a.iter().fold(0, |acc, x| acc + x); assert_eq!(sum, 6); }Run
Base usage: any示例
fn main() { let arr = [1, 2, 3]; let result1 = arr.iter().any(|&x| x != 2); let result2 = arr.iter().any(|x| *x != 2); // error: // the trait bound `&{integer}: std::cmp::PartialEq<{integer}>` is not satisfied // let result2 = arr.iter().any(|x| x != 2); assert_eq!(result1, true); assert_eq!(result2, true); }Run
Base usage: 使用fold对数组求和
fn main() { let arr = vec![1, 2, 3]; let sum1 = arr.iter().fold(0, |acc, x| acc + x); let sum2 = arr.iter().fold(0, |acc, x| acc + *x); let sum3 = arr.iter().fold(0, |acc, &x| acc + x); let sum4 = arr.into_iter().fold(0, |acc, x| acc + x); assert_eq!(sum1, 6); assert_eq!(sum2, 6); assert_eq!(sum3, 6); assert_eq!(sum4, 6); }Run
Base usage: 自定义集合MyVec实现FromIterator
实现FromIterator就可以拥有Collect的能力
use std::iter::FromIterator; #[derive(Debug)] struct MyVec(Vec<i32>); impl MyVec { fn new() -> MyVec { MyVec(Vec::new()) } fn add(&mut self, elem: i32) { self.0.push(elem); } } impl FromIterator<i32> for MyVec { fn from_iter<I: IntoIterator<Item = i32>>(iter: I) -> Self { let mut c = MyVec::new(); for i in iter { c.add(i); } c } } fn main() { let iter = (0..5).into_iter(); let c = MyVec::from_iter(iter); assert_eq!(c.0, vec![0, 1, 2, 3, 4]); let iter = (0..5).into_iter(); let c: MyVec = iter.collect(); assert_eq!(c.0, vec![0, 1, 2, 3, 4]); let iter = (0..5).into_iter(); let c = iter.collect::<MyVec>(); assert_eq!(c.0, vec![0, 1, 2, 3, 4]); }Run
Base usage: 自定义适配器
#[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct Step<I> { iter: I, skip: usize, } impl<I> Iterator for Step<I> where I: Iterator, { type Item = I::Item; fn next(&mut self) -> Option<I::Item> { let elt = self.iter.next(); if self.skip > 0 { self.iter.nth(self.skip - 1); } elt } } pub fn step<I>(iter: I, step: usize) -> Step<I> where I: Iterator, { assert!(step != 0); Step { iter: iter, skip: step - 1, } } pub trait IterExt: Iterator { fn step(self, n: usize) -> Step<Self> where Self: Sized, { step(self, n) } } impl<T: ?Sized> IterExt for T where T: Iterator {} fn main() { let arr = [1,2,3,4,5,6]; let sum = arr.iter().step(2).fold(0, |acc, x| acc + x); assert_eq!(9, sum); // [1, 3, 5] }Run
Base usage: 第三方包Itertools中实现的Positions适配器示例
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Debug)] pub struct Positions<I, F> { iter: I, f: F, count: usize, } pub fn positions<I, F>(iter: I, f: F) -> Positions<I, F> where I: Iterator, F: FnMut(I::Item) -> bool, { Positions { iter: iter, f: f, count: 0 } } impl<I, F> Iterator for Positions<I, F> where I: Iterator, F: FnMut(I::Item) -> bool, { type Item = usize; fn next(&mut self) -> Option<Self::Item> { while let Some(v) = self.iter.next() { let i = self.count; self.count = i + 1; if (self.f)(v) { return Some(i); } } None } fn size_hint(&self) -> (usize, Option<usize>) { (0, self.iter.size_hint().1) } } impl<I, F> DoubleEndedIterator for Positions<I, F> where I: DoubleEndedIterator + ExactSizeIterator, F: FnMut(I::Item) -> bool, { fn next_back(&mut self) -> Option<Self::Item> { while let Some(v) = self.iter.next_back() { if (self.f)(v) { return Some(self.count + self.iter.len()) } } None } } pub trait Itertools: Iterator { fn positions<P>(self, predicate: P) -> Positions<Self, P> where Self: Sized, P: FnMut(Self::Item) -> bool, { positions(self, predicate) } } impl<T: ?Sized> Itertools for T where T: Iterator {} fn main() { let data = vec![1, 2, 3, 3, 4, 6, 7, 9]; let r = data.iter().positions(|v| v % 3 == 0); let rev_r = data.iter().positions(|v| v % 3 == 0).rev(); for i in r { println!("{:?}", i); } // OUTPUT: 2 3 5 7 for i in rev_r { println!("{:?}", i); } // OUTPUT: 7 5 3 2 }Run