Ferrugem - Iterador e Fechamento

Neste capítulo, aprenderemos como iteradores e fechamentos funcionam no RUST.

Iteradores

Um iterador ajuda a iterar sobre uma coleção de valores, como matrizes, vetores, mapas, etc. Os iteradores implementam o traço Iterator que é definido na biblioteca padrão Rust. O método iter () retorna um objeto iterador da coleção. Os valores em um objeto iterador são chamados de itens. O método next () do iterador pode ser usado para percorrer os itens. O método next () retorna um valor Nenhum quando atinge o final da coleção.

O exemplo a seguir usa um iterador para ler os valores de uma matriz.

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());
}

Resultado

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

Se uma coleção como array ou Vector implementa o traço Iterator, então ele pode ser percorrido usando a sintaxe for ... in conforme mostrado abaixo-

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

Resultado

10 20 30

Os três métodos a seguir retornam um objeto iterador de uma coleção, onde T representa os elementos em uma coleção.

Sr. Não Métodos e Descrição
1

iter()

fornece um iterador sobre & T (referência a T)

2

into_iter()

dá um iterador sobre T

3

iter_mut()

dá um iterador sobre & mut T

Ilustração: iter ()

A função iter () usa o conceito de empréstimo. Ele retorna uma referência a cada elemento da coleção, deixando a coleção intacta e disponível para reutilização após o loop.

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
}

Resultado

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

Ilustração - into_iter ()

Esta função usa o conceito de propriedade. Ele move os valores da coleção para um objeto iter, ou seja, a coleção é consumida e não está mais disponível para reutilização.

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
}

Resultado

Hello Kannan
There is a rustacean among us!
Hello Kiran

Ilustração - for e iter_mut ()

Esta função é como a função iter () . No entanto, essa função pode modificar os elementos da coleção.

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
}

Resultado

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

Fecho

Fechamento se refere a uma função dentro de outra função. Estas são funções anônimas - funções sem um nome. O fechamento pode ser usado para atribuir uma função a uma variável. Isso permite que um programa passe uma função como parâmetro para outras funções. O fechamento também é conhecido como uma função embutida. As variáveis ​​na função externa podem ser acessadas por funções embutidas.

Sintaxe: Definindo um Fechamento

Uma definição de fechamento pode opcionalmente ter parâmetros. Os parâmetros são colocados entre duas barras verticais.

let closure_function = |parameter| {
   //logic
}

A sintaxe que invoca um Closure implementa Fntraços. Então, ele pode ser invocado com() sintaxe.

closure_function(parameter);    //invoking

Ilustração

O exemplo a seguir define um encerramento is_even dentro da função main () . O encerramento retorna verdadeiro se um número for par e retorna falso se o número for ímpar.

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

Resultado

13 is even ? false

Ilustração

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

A função main () declara uma variável val e um fechamento. O fechamento acessa a variável declarada na função externa main () .

Resultado

12