Rust - 迭代器和闭包



本章我们将学习 Rust 中迭代器和闭包的工作原理。

迭代器

迭代器帮助迭代遍历值的集合,例如数组、向量、映射等。迭代器实现了在 Rust 标准库中定义的 Iterator trait。`iter()` 方法返回集合的迭代器对象。迭代器对象中的值称为项目。迭代器的 `next()` 方法可用于遍历项目。当到达集合的末尾时,`next()` 方法返回 `None` 值。

下面的示例使用迭代器从数组中读取值。

fn main() {
   //declare an array
   let a = [10,20,30];

   let mut iter = a.iter(); 
   // fetch an iterator object for the array
   println!("{:?}",iter);

   //fetch individual values from the iterator object
   println!("{:?}",iter.next());
   println!("{:?}",iter.next());
   println!("{:?}",iter.next());
   println!("{:?}",iter.next());
}

输出

Iter([10, 20, 30])
Some(10)
Some(20)
Some(30)
None

如果像数组或向量这样的集合实现了 Iterator trait,那么可以使用 for...in 语法进行遍历,如下所示:

fn main() {
   let a = [10,20,30];
   let iter = a.iter();
   for data in iter{
      print!("{}\t",data);
   }
}

输出

10 20 30

以下 3 种方法从集合返回迭代器对象,其中 T 代表集合中的元素。

序号 方法和描述
1

iter()

提供对 &T(T 的引用)的迭代器

2

into_iter()

提供对 T 的迭代器

3

iter_mut()

提供对 &mut T 的迭代器

示例:iter()

iter() 函数使用借用概念。它返回对集合中每个元素的引用,在循环结束后,集合保持不变并可重复使用。

fn main() {
   let names = vec!["Kannan", "Mohtashim", "Kiran"];
   for name in names.iter() {
      match name {
         &"Mohtashim" => println!("There is a rustacean among us!"),
         _ => println!("Hello {}", name),
      }
   }
   println!("{:?}",names); 
   // reusing the collection after iteration
}

输出

Hello Kannan
There is a rustacean among us!
Hello Kiran
["Kannan", "Mohtashim", "Kiran"]

示例 - into_iter()

此函数使用所有权概念。它将集合中的值移动到 iter 对象中,即集合被消耗,不再可用。

fn main(){
   let names = vec!["Kannan", "Mohtashim", "Kiran"];
   for name in names.into_iter() {
      match name {
         "Mohtashim" => println!("There is a rustacean among us!"),
         _ => println!("Hello {}", name),
      }
   }
   // cannot reuse the collection after iteration
   //println!("{:?}",names); 
   //Error:Cannot access after ownership move
}

输出

Hello Kannan
There is a rustacean among us!
Hello Kiran

示例 - for 和 iter_mut()

此函数类似于 `iter()` 函数。但是,此函数可以修改集合中的元素。

fn main() {
   let mut names = vec!["Kannan", "Mohtashim", "Kiran"];
   for name in names.iter_mut() {
      match name {
         &mut "Mohtashim" => println!("There is a rustacean among us!"),
         _ => println!("Hello {}", name),
      }
   }
   println!("{:?}",names);
   //// reusing the collection after iteration
}

输出

Hello Kannan
There is a rustacean among us!
Hello Kiran
["Kannan", "Mohtashim", "Kiran"]

闭包

闭包指的是另一个函数内部的函数。它们是匿名函数——没有名称的函数。闭包可以用于将函数分配给变量。这允许程序将函数作为参数传递给其他函数。闭包也称为内联函数。外部函数中的变量可以被内联函数访问。

语法:定义闭包

闭包定义可以选择具有参数。参数包含在两个竖线之间。

let closure_function = |parameter| {
   //logic
}

调用闭包的语法实现 **Fn** trait。因此,它可以用 **()** 语法调用。

closure_function(parameter);    //invoking

示例

下面的示例在 `main()` 函数中定义了一个闭包 `is_even`。如果数字是偶数,则闭包返回 true;如果数字是奇数,则返回 false。

fn main(){
   let is_even = |x| {
      x%2==0
   };
   let no = 13;
   println!("{} is even ? {}",no,is_even(no));
}

输出

13 is even ? false

示例

fn main(){
   let val = 10; 
   // declared outside
   let closure2 = |x| {
      x + val //inner function accessing outer fn variable
   };
   println!("{}",closure2(2));
}

`main()` 函数声明了一个变量 `val` 和一个闭包。闭包访问在外部函数 `main()` 中声明的变量。

输出

12
广告