建设教育局官方网站,湖州网站建设方案,wordpress 获取当前用户id,cmseasy做网站简单吗迭代器用来遍历容器。 迭代器就是把容器中的所有元素按照顺序一个接一个的传递给处理逻辑。
Rust中的迭代器 标准库中定义了Iterator特性
trait Iterator {type Item;fn next(mut self) - OptionSelf::Item;
}实现了Iterator特性的结构体就是迭代器。 很多类…迭代器用来遍历容器。 迭代器就是把容器中的所有元素按照顺序一个接一个的传递给处理逻辑。
Rust中的迭代器 标准库中定义了Iterator特性
trait Iterator {type Item;fn next(mut self) - OptionSelf::Item;
}实现了Iterator特性的结构体就是迭代器。 很多类型都有iter()方法返回一个Iter结构体该结构体实现了Iterator特性。
一、创建迭代器
Rust中有三种类型的迭代器。 从容器创建迭代器有三种方法。 iter() 返回一个只读可重入迭代器迭代器元素的类型为 T iter_mut() 返回一个可写可重入迭代器迭代器元素的类型为 mut T into_iter() 返回一个只读不可重入迭代器迭代器元素的类型为 T
一iter() 返回一个只读可重入迭代器迭代器元素的类型为T。
例子
fn main() {let names vec![简单教程, 简明教程, 简单编程];let name names.iter();println!({:?}, names);
}二iter_mut() 返回一个可写可重入迭代器迭代器元素的类型为mut T。
例子
fn main() {let mut names vec![简单教程, 简明教程, 简单编程];let name names.iter_mut();println!({:?}, names);
}三into_iter() 返回一个只读不可重入迭代器迭代器元素的类型为T 它会把容器的值移动到迭代器中。 iter_into()之后的容器不可重用。
例子
fn main() {let mut names vec![简单教程, 简明教程, 简单编程];let name names.into_iter();println!({:?}, name);//println!({:?}, names);//去掉注释会编译错误
}二、使用迭代器
一返回迭代器元素个数 count() 消耗迭代器计算迭代次数并返回它。 此方法将反复调用next()直到遇到None并返回它看到Some的次数。 请注意即使迭代器没有任何元素也必须至少调用一次next() 溢出行为 该方法无法防止溢出因此对具有超过usize::MAX个元素的迭代器的元素进行计数会产生错误的结果或panics。 如果启用了调试断言则将保证panic。 Panics 如果迭代器具有多个usize::MAX元素则此函数可能为panic。 例子
let a [1, 2, 3];
assert_eq!(a.iter().count(), 3);二访问迭代器元素 nth(n) 返回迭代器的第n个元素。 计数从零开始因此nth(0) 返回第一个值nth(1) 返回第二个值依此类推。 请注意所有先前的元素以及返回的元素都将从迭代器中消耗。这意味着前面的元素将被丢弃并且在同一迭代器上多次调用nth(0)将返回不同的元素。 如果n大于或等于迭代器的长度则nth()将返回None。 例子
let a [1, 2, 3];
assert_eq!(a.iter().nth(1), Some(2));
多次调用nth() 不会回退迭代器
let a [1, 2, 3];
let mut iter a.iter();
assert_eq!(iter.nth(1), Some(2));
assert_eq!(iter.nth(1), None);
如果n大于或等于迭代器的长度则返回None
let a [1, 2, 3];
assert_eq!(a.iter().nth(10), None);last() 消耗迭代器返回最后一个元素。 此方法将评估迭代器直到返回None。 这样做时它会跟踪当前元素。 返回None之后last() 将返回它看到的最后一个元素。 例子
let a [1, 2, 3];
assert_eq!(a.iter().last(), Some(3));三遍历迭代器 1.使用next()方法遍历容器 例子
fn main() {let a [10,20,30];let mut iter a.iter(); // 从一个数组中返回迭代器println!({:?},iter);//使用next() 方法返回迭代器中的下一个元素println!({:?},iter.next());println!({:?},iter.next());println!({:?},iter.next());println!({:?},iter.next());
}
编译运行结果如下
Iter([10, 20, 30])
Some(10)
Some(20)
Some(30)
None2.使用for循环遍历 手动调用next()太麻烦了推荐使用for循环来使用迭代器。
1iter() 例子
fn main() {let names vec![简单教程, 简明教程, 简单编程];for name in names.iter() {println!({}, name);}println!({:?}, names);
}for name in names 实际上等价于 for name in names.iter()
2iter_mut() 例子
fn main() {let mut names vec![简单教程, 简明教程, 简单编程];for name in names.iter_mut() {println!({}, name);}println!({:?}, names);
}for name in mut names 实际上等价于 for name in names.iter_mut()
3into_iter() 例子
fn main() {let names vec![简单教程, 简明教程, 简单编程];for name in names.into_iter() {println!({}, name);}//println!({:?}, names); //去掉注释会编译错误
}for name in names 实际上等价于 for name in names.into_iter()
四迭代器转换成容器 collect() 将迭代器转换为容器。 使用collect()的最基本模式是将一个容器转换为另一个容器。 在一个容器上调用iter进行了一堆转换最后调用collect()。 由于collect()非常通用因此可能导致类型推断问题。 因此要指定类型或使用turbofish语法。 例子
let a [1, 2, 3];
let doubled: Veci32 a.iter().map(|x| x * 2).collect();
assert_eq!(vec![2, 4, 6], doubled);
使用自动推断类型
let a [1, 2, 3];
let doubled: Vec_ a.iter().map(|x| x * 2).collect();
assert_eq!(vec![2, 4, 6], doubled);
使用turbofish
let a [1, 2, 3];
let doubled a.iter().map(|x| x * 2).collect::Veci32();
assert_eq!(vec![2, 4, 6], doubled);
_ 与turbfish一起使用
let a [1, 2, 3];
let doubled a.iter().map(|x| x * 2).collect::Vec_();
assert_eq!(vec![2, 4, 6], doubled);五迭代器转换 map()方法可以转换迭代器 创建一个迭代器该迭代器每个元素是由原迭代器元素应用闭包得到。 可以这样考虑map() 如果您有一个元素类型为A的迭代器您想要元素类型为B的迭代器则可以使用map()传递一个把A转成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);如果您正在做某种副作用请首选for而不是map() 不要这样做
(0..5).map(|x| println!({x}));// 它甚至不会执行因为它很懒。Rust会就此警告您。而是用
for x in 0..5 {println!({x});
}flat_map() 创建一个迭代器其工作方式类似于map但它会将嵌套的结构展平。 map非常有用但仅当闭包产生值时才使用。 如果它产生一个迭代器则存在一个额外的间接层。flat_map() 将自行删除这个间接层。 您可以把flat_map(f) 视为map(f).flatten()。 map的闭包为每个元素返回一个值而flat_map ()的闭包为每个元素返回一个迭代器。 例子
let words [alpha, beta, gamma];
// chars() 返回一个迭代器
let merged: String words.iter().flat_map(|s| s.chars()).collect();
assert_eq!(merged, alphabetagamma);flatten() 创建一个去掉嵌套层的迭代器。比如二维向量变一维向量 例子
let data vec![vec![1, 2, 3, 4], vec![5, 6]];
let flattened data.into_iter().flatten().collec::Vecu8();
assert_eq!(flattened, [1, 2, 3, 4, 5, 6]);let words [alpha, beta, gamma];
// chars() 返回一个迭代器
let merged: String words.iter().map(|s| s.chars()).flatten().collect();
assert_eq!(merged, alphabetagamma);
您也可以用flat_map()来重写它
let words [alpha, beta, gamma];
// chars() 返回一个迭代器
let merged: String words.iter().flat_map(|s| s.chars()).collect();
assert_eq!(merged, alphabetagamma);展平一次只能删除一层嵌套
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]);在这里我们看到flatten()仅删除了一层嵌套。三维数组变二维而不是一维。要获得一维您必须再次flatten()。
六enumerate 创建一个迭代器该迭代器元素是(i, val)其中i是当前迭代索引val是迭代器返回的值。 enumerate()保持其计数为usize。 溢出行为 该方法无法防止溢出因此枚举多个usize::MAX元素会产生错误的结果或panics。 如果启用了调试断言则将保证panic。 Panics 如果要返回的索引将溢出usize则返回的迭代器可能为panic。 例子
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);七逆转迭代器 rev 反转迭代器的方向。 通常迭代器从左到右进行迭代。 使用rev() 之后迭代器将改为从右向左进行迭代。 例子
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);八截取迭代器 take(n) 创建一个迭代器它的元素是原迭代器的前n个元素。如果原迭代器元素数小于n则返回原迭代器所有元素。 例子
let a [1, 2, 3];
let mut iter a.iter().take(2);
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
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);九其他 max 返回迭代器的最大元素。 如果几个元素最大相等则返回最后一个元素。如果迭代器为空则返回None。 请注意由于NaN不可比较f32/f64没有实现Ord。 您可以使用Iterator::reduce解决此问题
assert_eq!([2.4, f32::NAN, 1.3].into_iter().reduce(f32::max).unwrap(),2.4);例子
let a [1, 2, 3];
let b: Vec Vec::new();
assert_eq!(a.iter().max(), Some(3));
assert_eq!(b.iter().max(), None);min 返回迭代器的最小元素。 如果几个元素相等地最小则返回第一个元素。 如果迭代器为空则返回None。 请注意由于NaN不可比较f32/f64没有实现Ord。您可以使用Iterator::reduce解决此问题
assert_eq!([2.4, f32::NAN, 1.3].into_iter().reduce(f32::min).unwrap(),1.3);例子
let a [1, 2, 3];
let b: Vec Vec::new();
assert_eq!(a.iter().min(), Some(1));
assert_eq!(b.iter().min(), None);sum 对迭代器的元素求和。 获取每个元素将它们添加在一起然后返回结果。 空的迭代器将返回该类型的零值。 sum()可用于对任何实现Sum的类型求和包括Option和Result。 Panics 当调用sum() 并返回原始整数类型时如果计算溢出并且启用了调试断言则此方法将为panic。 例子
let a [1, 2, 3];
let sum: i32 a.iter().sum();
assert_eq!(sum, 6);