Учебники

Rust — Итератор и Закрытие

В этой главе мы узнаем, как итераторы и замыкания работают в RUST.

итераторы

Итератор помогает перебирать коллекцию значений, таких как массивы, векторы, карты и т. Д. Итераторы реализуют черту Iterator, определенную в стандартной библиотеке Rust. Метод 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

Если коллекция, такая как массив или Vector, реализует черту Iterator, то ее можно просмотреть, используя синтаксис 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 представляет элементы в коллекции.

Sr.No Методы и описание
1

ITER ()

дает итератор над & T (ссылка на T)

2

into_iter ()

дает итератор над T

3

iter_mut ()

дает итератор над & Mut T

ITER ()

дает итератор над & T (ссылка на T)

into_iter ()

дает итератор над T

iter_mut ()

дает итератор над & Mut T

Иллюстрация: ИТЭР ()

Функция 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

Иллюстрация — для и 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
}

Синтаксис, вызывающий Closure, реализует черты Fn . Таким образом, он может быть вызван с помощью синтаксиса () .

closure_function(parameter);    //invoking

иллюстрация

В следующем примере определяется замыкание is_even внутри функции main () . Закрытие возвращает 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 () .