马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一、迭代与循环
1.循环
界说:循环是一种控制流结构,它会反复实行一组语句,直到满意某个条件。
控制条件:循环通常包罗一个条件表达式,只有在条件为真时,循环体中的语句才会实行。
退出条件:循环实行直到条件不再满意,大概通过break、语句显式停止循环。
使用场景:实用于须要反复实行某个操纵直到满意某个条件的情况。
2.迭代iteration
·界说:选代是对序列中的元素举行逐个访问的过程。
·控制条件:迭代通常使用迭代器(lterator)来实现,迭代器提供了对序列元素的访问和操纵。
·退出条件:通常不须要显式的退出条件,迭代器会在处理处罚完全部元素后主动克制。
·使用场景:实用于须要遍历数据结构中的元素的情况,比方数组、切片、聚集等。
3.区别
·1.循环是一种控制流结构,它反复实行一组语句。
·2.送代是对序列中的元素举行逐个访问的过程,通常使用迭代器实现。
·3.循环可以是有限的(通过设置退出条件)或无穷的(使用loop)关键字)。
·4.迭代器提供了一种更抽象的方式来处理处罚序列,使得代码更具可读性和机动性。
在Rust中,循环和迭代性能的差距大概会取决于详细的使用情况和编译器的优化。绝大多数情况下,Rust的迭代器是颠末优化的,可以到达或靠近手动编写循环的性能水平。
- // &[i32] &Vec
- // loop
- fn sum_with_loop(arr: &[i32]) -> i32 {
-
-
- let mut sum = 0;
- for &item in arr {
-
-
- sum += item;
- }
- sum
- }
- // iter
- fn sum_with_iter(arr: &[i32]) -> i32 {
-
-
- arr.iter().sum()
- }
- fn main() {
-
-
- const ARRAY_SIZE: usize = 10000;
- let array: Vec<i32> = (1..=ARRAY_SIZE as i32).collect();
- let sum1 = sum_with_loop(&array);
- println!("sum loop {}", sum1);
- let sum2 = sum_with_iter(&array);
- println!("sum loop {}", sum2);
- }
复制代码 编译及运行:
- ▶ cargo run
- Compiling ch5_iter_loop v0.1.0 (/home/wangji/code/rust/2024_rust/rust_project/ch4_iter_loop)
- Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.20s
- Running `target/debug/ch5_iter_loop`
- sum loop 50005000
- sum loop 50005000
复制代码 二、Intoiterator、Iterator和Iter之间的关系
1.Intolterator
Intolterator是一个RustTrait,它界说了一种将范例转换为迭代器的本事。
该Trait包罗一个方法into_iter,该方法返回一个实现了IteratorTrait的迭代器。
通常,当你有一个范例,渴望可以或许对其举行迭代时,你会实现IntolteratorTrait来提供将该范例转换为迭代器的方法。
2.Iterator Trait
Iterator是Rust尺度库中的Trait,界说了一种访问序列元素的方式。
·它包罗了一系列方法,如next、map、filter、sum、等,用于对序列举行差异范例的操纵。
·通过实现Iterator丶Trait,你可以创建自界说的迭代器,以界说怎样迭代你的范例中的元素。
- pub trait Iterator{
-
-
- type Item;
- fn next(&mut self) -> Option<Self::Item>;
- }
复制代码 3. 源码中经常出现的iter
·Iter是IteratorTrait的一个详细实现,通常用于对聚集中的元素举行迭代。
·在Rust中,你会经常看到Iter,特别是在对数组、切片等聚集范例举行迭代时。
·通过lntolteratorTrait,你可以获取到一个特定范例的迭代器,比如Iter,然后可以使用IteratorTrait的方法举行操纵。
- fn main() {
-
-
- // vec
- let v = vec![1, 2, 3, 4, 5]; // intoIterator 特质 into_iter
- // 转换为迭代器
- let iter = v.into_iter(); // move 所有权转移 类似ppt中的Iter Iterator的特质对象
- let sum: i32 = iter.sum();
- println!("sum: {}", sum);
- // println!("{:?}", v)
- // array
- let array = [1, 2, 3, 4, 5];
- let iter: std::slice::Iter<'_, i32> = array.iter();//所有权没有转移
- let sum: i32 = iter.sum();
- println!("sum: {}", sum);
- println!("{:?}", array);
- // chars
- let text = "hello, world!";
- let iter = text.chars();//所有权没有转移
- // 等价于let uppercase:String = iter.map(|c| c.to_ascii_uppercase()).collect();
- // collect表示迭代器的下一个, <String>表示返回的类型是String
- let uppercase = iter.map(|c| c.to_ascii_uppercase()).collect::<String>();
- println!("uppercase: {}", uppercase);
- println!("{:?}", text);
- }
复制代码 编译及运行
- ▶ cargo run
- Compiling ch2_intoiterator_iterator_iter v0.1.0 (/home/wangji/code/rust/2024_rust/rust_project/ch5_intoiterator_iterator_iter)
- Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.04s
- Running `target/debug/ch2_intoiterator_iterator_iter`
- sum: 15
- sum: 15
- [1, 2, 3, 4, 5]
- uppercase: HELLO, WORLD!
- "hello, world!"
复制代码 三、获取迭代器的三种方法iter(),iter_mut()和into_iter()
into_ 之类的,都是拿走全部权,_mut 之类的都是可变借用,剩下的就是不可变借用。
1.iter()方法, 是借用
iter()方法返回一个不可变引用的迭代器,用于只读访问聚集的元素。
该方法实用于你渴望在不修改聚集的情况下迭代元素的场景。
2.iter_mut()方法,是可变借用
iter_mut()方法返回一个可变引用的迭代器,用于答应修改聚集中的元素。
该方法实用于你渴望在迭代过程中修改聚集元素的场景。
- fn main() {
-
-
- let values = vec![1, 2, 3];
- for v in values.into_iter() {
-
-
- println!("{}", v)
- }
- // 下面的代码将报错,因为 values 的所有权在上面 `for` 循环中已经被转移走
- // println!("{:?}",values);
- let values = vec![1, 2, 3];
- let _values_iter = values.iter();
- // 不会报错,因为 values_iter 只是借用了 values 中的元素
- println!("{:?}", values);
- let mut values = vec![1, 2, 3];
- // 对 values 中的元素进行可变借用
- let mut values_iter_mut = values.iter_mut();
- // 取出第一个元素,并修改为0
- if let Some(v) = values_iter_mut.next() {
-
-
- *v = 0;
- }
- // 输出[0, 2, 3]
- println!("{:?}", values);
- }
复制代码 .iter() 方法实现的迭代器,调用 next 方法返回的范例是 Some(&T)
.iter_mut() 方法实现的迭代器,调用 next 方法返回的范例是 Some(&mut T),因此在 if let Some(v) = values_iter_mut.next() 中,v 的范例是 &mut i32,终极我们可以通过 *v = 0 的方式修改其值
3.into_iter()方法—只管写,会夺走全部权
into_iter()方法返回一个拥有全部权的迭代器,该迭代器会斲丧聚集自己,将全部权转移到迭代器。
该方法实用于你渴望在迭代过程中拥有聚集的全部权,以便举行斲丧性的操纵,如移除元素。
- fn main() {
-
-
- let vec = vec![1, 2, 3, 4, 5];
- // iter()
- for &item in vec.iter() {
-
-
- println!("{}", item);
- }
- println!("{:?}", vec);
- // 可变引用
- let mut vec = vec![1, 2, 3, 4, 5];
- for item in vec.iter_mut() {
-
-
- *item *= 2;
- }
- // 所有权转移
- println!("{:?}", vec);
- let vec = vec![1, 2, 3, 4, 5];
- for item in vec.into_iter() {
-
-
- println!("{}", item);
- }
-
复制代码 |