Ruggine - Iteratore e chiusura

In questo capitolo impareremo come funzionano gli iteratori e le chiusure in RUST.

Iteratori

Un iteratore aiuta a iterare su una raccolta di valori come array, vettori, mappe, ecc. Gli iteratori implementano il tratto Iterator definito nella libreria standard Rust. Il metodo iter () restituisce un oggetto iteratore della raccolta. I valori in un oggetto iteratore sono chiamati elementi. Il metodo next () dell'iteratore può essere utilizzato per attraversare gli elementi. Il metodo next () restituisce un valore None quando raggiunge la fine della raccolta.

L'esempio seguente usa un iteratore per leggere i valori da un array.

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

Produzione

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

Se una raccolta come array o Vector implementa il tratto Iterator, può essere attraversata usando il for ... nella sintassi come mostrato di seguito-

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

Produzione

10 20 30

I 3 metodi seguenti restituiscono un oggetto iteratore da una raccolta, dove T rappresenta gli elementi in una raccolta.

Suor n Metodi e descrizione
1

iter()

fornisce un iteratore su & T (riferimento a T)

2

into_iter()

fornisce un iteratore su T

3

iter_mut()

fornisce un iteratore su & mut T

Illustrazione: iter ()

La funzione iter () utilizza il concetto di prestito. Restituisce un riferimento a ogni elemento della raccolta, lasciando la raccolta intatta e disponibile per il riutilizzo dopo il ciclo.

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
}

Produzione

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

Illustrazione - into_iter ()

Questa funzione utilizza il concetto di proprietà. Sposta i valori nella raccolta in un oggetto iter, ovvero la raccolta viene consumata e non è più disponibile per il riutilizzo.

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
}

Produzione

Hello Kannan
There is a rustacean among us!
Hello Kiran

Illustrazione - for and iter_mut ()

Questa funzione è come la funzione iter () . Tuttavia, questa funzione può modificare gli elementi all'interno della raccolta.

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
}

Produzione

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

Chiusura

La chiusura si riferisce a una funzione all'interno di un'altra funzione. Queste sono funzioni anonime - funzioni senza nome. La chiusura può essere utilizzata per assegnare una funzione a una variabile. Ciò consente a un programma di passare una funzione come parametro ad altre funzioni. La chiusura è anche nota come funzione inline. È possibile accedere alle variabili nella funzione esterna dalle funzioni inline.

Sintassi: definizione di una chiusura

Una definizione di chiusura può facoltativamente avere parametri. I parametri sono racchiusi tra due barre verticali.

let closure_function = |parameter| {
   //logic
}

La sintassi che richiama una chiusura viene implementata Fntratti. Quindi, può essere invocato con() sintassi.

closure_function(parameter);    //invoking

Illustrazione

L'esempio seguente definisce una chiusura is_even all'interno della funzione main () . La chiusura restituisce vero se un numero è pari e restituisce falso se il numero è dispari.

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

Produzione

13 is even ? false

Illustrazione

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

La funzione main () dichiara una variabile val e una chiusura. La chiusura accede alla variabile dichiarata nella funzione esterna main () .

Produzione

12